📄 uploadclient.cpp
字号:
oldreqfile->RemoveUploadingClient(this);
}
void CUpDownClient::AddReqBlock(Requested_Block_Struct* reqblock)
{
if(GetUploadState() != US_UPLOADING) {
if(thePrefs.GetLogUlDlEvents())
AddDebugLogLine(DLP_LOW, false, _T("UploadClient: Client tried to add req block when not in upload slot! Prevented req blocks from being added. %s"), DbgGetClientInfo());
delete reqblock;
return;
}
for (POSITION pos = m_DoneBlocks_list.GetHeadPosition(); pos != 0; ){
const Requested_Block_Struct* cur_reqblock = m_DoneBlocks_list.GetNext(pos);
if (reqblock->StartOffset == cur_reqblock->StartOffset && reqblock->EndOffset == cur_reqblock->EndOffset){
delete reqblock;
return;
}
}
for (POSITION pos = m_BlockRequests_queue.GetHeadPosition(); pos != 0; ){
const Requested_Block_Struct* cur_reqblock = m_BlockRequests_queue.GetNext(pos);
if (reqblock->StartOffset == cur_reqblock->StartOffset && reqblock->EndOffset == cur_reqblock->EndOffset){
delete reqblock;
return;
}
}
m_BlockRequests_queue.AddTail(reqblock);
}
uint32 CUpDownClient::SendBlockData(){
DWORD curTick = ::GetTickCount();
uint64 sentBytesCompleteFile = 0;
uint64 sentBytesPartFile = 0;
uint64 sentBytesPayload = 0;
if(GetFileUploadSocket() && (m_ePeerCacheUpState != PCUS_WAIT_CACHE_REPLY)) {
CEMSocket* s = GetFileUploadSocket();
if(m_pPCUpSocket && IsUploadingToPeerCache()) {
// Check if filedata has been sent via the normal socket since last call.
uint64 sentBytesCompleteFileNormalSocket = socket->GetSentBytesCompleteFileSinceLastCallAndReset();
uint64 sentBytesPartFileNormalSocket = socket->GetSentBytesPartFileSinceLastCallAndReset();
if(thePrefs.GetVerbose() && (sentBytesCompleteFileNormalSocket + sentBytesPartFileNormalSocket > 0)) {
AddDebugLogLine(false, _T("Sent file data via normal socket when in PC mode. Bytes: %I64i."), sentBytesCompleteFileNormalSocket + sentBytesPartFileNormalSocket);
}
}
// Extended statistics information based on which client software and which port we sent this data to...
// This also updates the grand total for sent bytes, etc. And where this data came from.
sentBytesCompleteFile = s->GetSentBytesCompleteFileSinceLastCallAndReset();
sentBytesPartFile = s->GetSentBytesPartFileSinceLastCallAndReset();
thePrefs.Add2SessionTransferData(GetClientSoft(), GetUserPort(), false, true, sentBytesCompleteFile, (IsFriend()&& GetFriendSlot()));
thePrefs.Add2SessionTransferData(GetClientSoft(), GetUserPort(), true, true, sentBytesPartFile, (IsFriend()&& GetFriendSlot()));
m_nTransferedUp += sentBytesCompleteFile + sentBytesPartFile;
credits->AddUploaded(sentBytesCompleteFile + sentBytesPartFile, GetIP());
sentBytesPayload = s->GetSentPayloadSinceLastCallAndReset();
m_nCurQueueSessionPayloadUp += sentBytesPayload;
if(theApp.uploadqueue->CheckForTimeOver(this)) {
theApp.uploadqueue->RemoveFromUploadQueue(this, _T("Completed transfer"), true);
//OP_OUTOFPARTREQS will tell the downloading client to go back to OnQueue..
//The main reason for this is that if we put the client back on queue and it goes
//back to the upload before the socket times out... We get a situation where the
//downloader things it already send the requested blocks and the uploader thinks
//the downloader didn't send any reqeust blocks. Then the connection times out..
//I did some tests with eDonkey also and it seems to work well with them also..
if (thePrefs.GetDebugClientTCPLevel() > 0)
DebugSend("OP__OutOfPartReqs", this);
Packet* pCancelTransferPacket = new Packet(OP_OUTOFPARTREQS, 0);
theStats.AddUpDataOverheadFileRequest(pCancelTransferPacket->size);
socket->SendPacket(pCancelTransferPacket,true,true);
theApp.uploadqueue->AddClientToQueue(this,true);
}
else {
// read blocks from file and put on socket
CreateNextBlockPackage();
}
}
if(sentBytesCompleteFile + sentBytesPartFile > 0 ||
m_AvarageUDR_list.GetCount() == 0 || (curTick - m_AvarageUDR_list.GetTail().timestamp) > 1*1000) {
// Store how much data we've transfered this round,
// to be able to calculate average speed later
// keep sum of all values in list up to date
TransferredData newitem = {sentBytesCompleteFile + sentBytesPartFile, curTick};
m_AvarageUDR_list.AddTail(newitem);
sumavgUDR += sentBytesCompleteFile + sentBytesPartFile;
}
// remove to old values in list
while (m_AvarageUDR_list.GetCount() > 0 && (curTick - m_AvarageUDR_list.GetHead().timestamp) > 10*1000) {
// keep sum of all values in list up to date
sumavgUDR -= m_AvarageUDR_list.RemoveHead().datalen;
}
// Calculate average speed for this slot
if(m_AvarageUDR_list.GetCount() > 0 && (curTick - m_AvarageUDR_list.GetHead().timestamp) > 0 && GetUpStartTimeDelay() > 2*1000) {
m_nUpDatarate = ((ULONGLONG)sumavgUDR*1000) / (curTick-m_AvarageUDR_list.GetHead().timestamp);
} else {
// not enough values to calculate trustworthy speed. Use -1 to tell this
m_nUpDatarate = 0; //-1;
}
// Check if it's time to update the display.
if (curTick-m_lastRefreshedULDisplay > MINWAIT_BEFORE_ULDISPLAY_WINDOWUPDATE+(uint32)(rand()*800/RAND_MAX)) {
// Update display
theApp.emuledlg->transferwnd->uploadlistctrl.RefreshClient(this);
theApp.emuledlg->transferwnd->clientlistctrl.RefreshClient(this);
m_lastRefreshedULDisplay = curTick;
}
return sentBytesCompleteFile + sentBytesPartFile;
}
/**
* See description for CEMSocket::TruncateQueues().
*/
void CUpDownClient::FlushSendBlocks(){ // call this when you stop upload, or the socket might be not able to send
if (socket) //socket may be NULL...
socket->TruncateQueues();
}
void CUpDownClient::SendHashsetPacket(char* forfileid){
CKnownFile* file = theApp.sharedfiles->GetFileByID((uchar*)forfileid);
if (!file){
CheckFailedFileIdReqs((uchar*)forfileid);
throw GetResString(IDS_ERR_REQ_FNF) + _T(" (SendHashsetPacket)");
}
CSafeMemFile data(1024);
data.WriteHash16(file->GetFileHash());
UINT parts = file->GetHashCount();
data.WriteUInt16(parts);
for (UINT i = 0; i < parts; i++)
data.WriteHash16(file->GetPartHash(i));
if (thePrefs.GetDebugClientTCPLevel() > 0)
DebugSend("OP__HashSetAnswer", this, forfileid);
Packet* packet = new Packet(&data);
packet->opcode = OP_HASHSETANSWER;
theStats.AddUpDataOverheadFileRequest(packet->size);
socket->SendPacket(packet,true,true);
}
void CUpDownClient::ClearUploadBlockRequests()
{
FlushSendBlocks();
for (POSITION pos = m_BlockRequests_queue.GetHeadPosition();pos != 0;)
delete m_BlockRequests_queue.GetNext(pos);
m_BlockRequests_queue.RemoveAll();
for (POSITION pos = m_DoneBlocks_list.GetHeadPosition();pos != 0;)
delete m_DoneBlocks_list.GetNext(pos);
m_DoneBlocks_list.RemoveAll();
}
void CUpDownClient::SendRankingInfo(){
if (!ExtProtocolAvailable())
return;
uint16 nRank = theApp.uploadqueue->GetWaitingPosition(this);
if (!nRank)
return;
Packet* packet = new Packet(OP_QUEUERANKING,12,OP_EMULEPROT);
PokeUInt16(packet->pBuffer+0, nRank);
memset(packet->pBuffer+2, 0, 10);
if (thePrefs.GetDebugClientTCPLevel() > 0)
DebugSend("OP__QueueRank", this);
theStats.AddUpDataOverheadFileRequest(packet->size);
socket->SendPacket(packet,true,true);
}
void CUpDownClient::SendCommentInfo(/*const*/ CKnownFile *file)
{
if (!m_bCommentDirty || file == NULL || !ExtProtocolAvailable() || m_byAcceptCommentVer < 1)
return;
m_bCommentDirty = false;
uint8 rating = file->GetFileRating();
const CString& desc = file->GetFileComment();
if (file->GetFileRating() == 0 && desc.IsEmpty())
return;
CSafeMemFile data(256);
data.WriteUInt8(rating);
data.WriteLongString(desc, GetUnicodeSupport());
if (thePrefs.GetDebugClientTCPLevel() > 0)
DebugSend("OP__FileDesc", this, (char*)file->GetFileHash());
Packet *packet = new Packet(&data,OP_EMULEPROT);
packet->opcode = OP_FILEDESC;
theStats.AddUpDataOverheadFileRequest(packet->size);
socket->SendPacket(packet,true);
}
void CUpDownClient::AddRequestCount(const uchar* fileid)
{
for (POSITION pos = m_RequestedFiles_list.GetHeadPosition(); pos != 0; ){
Requested_File_Struct* cur_struct = m_RequestedFiles_list.GetNext(pos);
if (!md4cmp(cur_struct->fileid,fileid)){
if (::GetTickCount() - cur_struct->lastasked < MIN_REQUESTTIME && !GetFriendSlot()){
if (GetDownloadState() != DS_DOWNLOADING)
cur_struct->badrequests++;
if (cur_struct->badrequests == BADCLIENTBAN){
Ban();
}
}
else{
if (cur_struct->badrequests)
cur_struct->badrequests--;
}
cur_struct->lastasked = ::GetTickCount();
return;
}
}
Requested_File_Struct* new_struct = new Requested_File_Struct;
md4cpy(new_struct->fileid,fileid);
new_struct->lastasked = ::GetTickCount();
new_struct->badrequests = 0;
m_RequestedFiles_list.AddHead(new_struct);
}
void CUpDownClient::UnBan()
{
theApp.clientlist->AddTrackClient(this);
theApp.clientlist->RemoveBannedClient(GetIP());
SetUploadState(US_NONE);
ClearWaitStartTime();
theApp.emuledlg->transferwnd->ShowQueueCount(theApp.uploadqueue->GetWaitingUserCount());
for (POSITION pos = m_RequestedFiles_list.GetHeadPosition();pos != 0;)
{
Requested_File_Struct* cur_struct = m_RequestedFiles_list.GetNext(pos);
cur_struct->badrequests = 0;
cur_struct->lastasked = 0;
}
}
void CUpDownClient::Ban(LPCTSTR pszReason)
{
theApp.clientlist->AddTrackClient(this);
if (!IsBanned()){
if (thePrefs.GetLogBannedClients())
AddDebugLogLine(false,_T("Banned: %s; %s"), pszReason==NULL ? _T("Aggressive behaviour") : pszReason, DbgGetClientInfo());
}
#ifdef _DEBUG
else{
if (thePrefs.GetLogBannedClients())
AddDebugLogLine(false,_T("Banned: (refreshed): %s; %s"), pszReason==NULL ? _T("Aggressive behaviour") : pszReason, DbgGetClientInfo());
}
#endif
theApp.clientlist->AddBannedClient(GetIP());
SetUploadState(US_BANNED);
theApp.emuledlg->transferwnd->ShowQueueCount(theApp.uploadqueue->GetWaitingUserCount());
theApp.emuledlg->transferwnd->queuelistctrl.RefreshClient(this);
if (socket != NULL && socket->IsConnected())
socket->ShutDown(SD_RECEIVE); // let the socket timeout, since we dont want to risk to delete the client right now. This isnt acutally perfect, could be changed later
}
uint32 CUpDownClient::GetWaitStartTime() const
{
if (credits == NULL){
ASSERT ( false );
return 0;
}
uint32 dwResult = credits->GetSecureWaitStartTime(GetIP());
if (dwResult > m_dwUploadTime && IsDownloading()){
//this happens only if two clients with invalid securehash are in the queue - if at all
dwResult = m_dwUploadTime-1;
if (thePrefs.GetVerbose())
DEBUG_ONLY(AddDebugLogLine(false,_T("Warning: CUpDownClient::GetWaitStartTime() waittime Collision (%s)"),GetUserName()));
}
return dwResult;
}
void CUpDownClient::SetWaitStartTime(){
if (credits == NULL){
return;
}
credits->SetSecWaitStartTime(GetIP());
}
void CUpDownClient::ClearWaitStartTime(){
if (credits == NULL){
return;
}
credits->ClearWaitStartTime();
}
bool CUpDownClient::GetFriendSlot() const
{
if (credits && theApp.clientcredits->CryptoAvailable()){
switch(credits->GetCurrentIdentState(GetIP())){
case IS_IDFAILED:
case IS_IDNEEDED:
case IS_IDBADGUY:
return false;
}
}
return m_bFriendSlot;
}
CEMSocket* CUpDownClient::GetFileUploadSocket(bool log) {
if(m_pPCUpSocket && (IsUploadingToPeerCache() || m_ePeerCacheUpState == PCUS_WAIT_CACHE_REPLY)) {
if(thePrefs.GetVerbose() && log)
AddDebugLogLine(false, _T("%s got peercache socket."), DbgGetClientInfo());
return m_pPCUpSocket;
} else {
if(thePrefs.GetVerbose() && log)
AddDebugLogLine(false, _T("%s got normal socket."), DbgGetClientInfo());
return socket;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -