📄 clientudpsocket.cpp
字号:
DebugRecv("OP_ReaskFilePing", sender, (char*)reqfilehash, ip);
//Make sure we are still thinking about the same file
if (md4cmp(reqfilehash, sender->GetUploadFileID()) == 0)
{
sender->AddAskedCount();
sender->SetLastUpRequest();
//I messed up when I first added extended info to UDP
//I should have originally used the entire ProcessExtenedInfo the first time.
//So now I am forced to check UDPVersion to see if we are sending all the extended info.
//For now on, we should not have to change anything here if we change
//anything to the extended info data as this will be taken care of in ProcessExtendedInfo()
//Update extended info.
if (sender->GetUDPVersion() > 3)
{
sender->ProcessExtendedInfo(&data_in, reqfile);
}
//Update our complete source counts.
else if (sender->GetUDPVersion() > 2)
{
uint16 nCompleteCountLast= sender->GetUpCompleteSourcesCount();
uint16 nCompleteCountNew = data_in.ReadUInt16();
sender->SetUpCompleteSourcesCount(nCompleteCountNew);
if (nCompleteCountLast != nCompleteCountNew)
{
reqfile->UpdatePartsInfo();
}
}
CSafeMemFile data_out(128);
if(sender->GetUDPVersion() > 3)
{
if (reqfile->IsPartFile())
((CPartFile*)reqfile)->WritePartStatus(&data_out);
else
data_out.WriteUInt16(0);
}
data_out.WriteUInt16(theApp.uploadqueue->GetWaitingPosition(sender));
if (thePrefs.GetDebugClientUDPLevel() > 0)
DebugSend("OP__ReaskAck", sender);
Packet* response = new Packet(&data_out, OP_EMULEPROT);
response->opcode = OP_REASKACK;
theStats.AddUpDataOverheadFileRequest(response->size);
theApp.clientudp->SendPacket(response, ip, port);
}
else
{
AddDebugLogLine(false, _T("Client UDP socket; ReaskFilePing; reqfile does not match"));
TRACE(_T("reqfile: %s\n"), DbgGetFileInfo(reqfile->GetFileHash()));
TRACE(_T("sender->GetRequestFile(): %s\n"), sender->GetRequestFile() ? DbgGetFileInfo(sender->GetRequestFile()->GetFileHash()) : _T("(null)"));
}
}
else
{
if (thePrefs.GetDebugClientUDPLevel() > 0)
DebugRecv("OP_ReaskFilePing", NULL, (char*)reqfilehash, ip);
if (((uint32)theApp.uploadqueue->GetWaitingUserCount() + 50) > thePrefs.GetQueueSize())
{
if (thePrefs.GetDebugClientUDPLevel() > 0)
DebugSend("OP__QueueFull", NULL);
Packet* response = new Packet(OP_QUEUEFULL,0,OP_EMULEPROT);
theStats.AddUpDataOverheadFileRequest(response->size);
SendPacket(response, ip, port);
}
}
break;
}
case OP_QUEUEFULL:
{
theStats.AddDownDataOverheadFileRequest(size);
CUpDownClient* sender = theApp.downloadqueue->GetDownloadClientByIP_UDP(ip, port);
if (thePrefs.GetDebugClientUDPLevel() > 0)
DebugRecv("OP_QueueFull", sender, NULL, ip);
if (sender){
sender->SetRemoteQueueFull(true);
sender->UDPReaskACK(0);
}
break;
}
case OP_REASKACK:
{
theStats.AddDownDataOverheadFileRequest(size);
CUpDownClient* sender = theApp.downloadqueue->GetDownloadClientByIP_UDP(ip, port);
if (thePrefs.GetDebugClientUDPLevel() > 0)
DebugRecv("OP_ReaskAck", sender, NULL, ip);
if (sender){
CSafeMemFile data_in((BYTE*)packet,size);
if ( sender->GetUDPVersion() > 3 )
{
sender->ProcessFileStatus(true, &data_in, sender->GetRequestFile());
}
uint16 nRank = data_in.ReadUInt16();
sender->SetRemoteQueueFull(false);
sender->UDPReaskACK(nRank);
sender->AddAskedCountDown();
}
break;
}
case OP_FILENOTFOUND:
{
theStats.AddDownDataOverheadFileRequest(size);
CUpDownClient* sender = theApp.downloadqueue->GetDownloadClientByIP_UDP(ip, port);
if (thePrefs.GetDebugClientUDPLevel() > 0)
DebugRecv("OP_FileNotFound", sender, NULL, ip);
if (sender){
sender->UDPReaskFNF(); // may delete 'sender'!
sender = NULL;
}
break;
}
case OP_PORTTEST:
{
theStats.AddDownDataOverheadOther(size);
if (size==1)
if (packet[0]==0x12) {
bool ret=theApp.listensocket->SendPortTestReply('1',true);
theApp.AddDebugLogLine(true,_T("UDP Portcheck packet arrived - ACK sent back (status=%i)"),ret );
}
break;
}
default:
theStats.AddDownDataOverheadOther(size);
if (thePrefs.GetDebugClientUDPLevel() > 0)
{
CUpDownClient* sender = theApp.downloadqueue->GetDownloadClientByIP_UDP(ip, port);
Debug(_T("Unknown client UDP packet: host=%s:%u (%s) opcode=0x%02x size=%u\n"), ipstr(ip), port, sender ? sender->DbgGetClientInfo() : _T(""), opcode, size);
}
return false;
}
return true;
}
void CClientUDPSocket::OnSend(int nErrorCode){
if (nErrorCode){
if (thePrefs.GetVerbose())
AddDebugLogLine(false, _T("Error: Client UDP socket, error on send event: %s"), GetErrorMessage(nErrorCode, 1));
return;
}
// ZZ:UploadBandWithThrottler (UDP) -->
sendLocker.Lock();
m_bWouldBlock = false;
if(!controlpacket_queue.IsEmpty()) {
theApp.uploadBandwidthThrottler->QueueForSendingControlPacket(this);
}
sendLocker.Unlock();
// <-- ZZ:UploadBandWithThrottler (UDP)
}
SocketSentBytes CClientUDPSocket::SendControlData(uint32 maxNumberOfBytesToSend, uint32 minFragSize){ // ZZ:UploadBandWithThrottler (UDP)
// ZZ:UploadBandWithThrottler (UDP) -->
// NOTE: *** This function is invoked from a *different* thread!
sendLocker.Lock();
uint32 sentBytes = 0;
// <-- ZZ:UploadBandWithThrottler (UDP)
while (!controlpacket_queue.IsEmpty() && !IsBusy() && sentBytes < maxNumberOfBytesToSend){ // ZZ:UploadBandWithThrottler (UDP)
UDPPack* cur_packet = controlpacket_queue.GetHead();
if( GetTickCount() - cur_packet->dwTime < UDPMAXQUEUETIME )
{
char* sendbuffer = new char[cur_packet->packet->size+2];
memcpy(sendbuffer,cur_packet->packet->GetUDPHeader(),2);
memcpy(sendbuffer+2,cur_packet->packet->pBuffer,cur_packet->packet->size);
if (!SendTo(sendbuffer, cur_packet->packet->size+2, cur_packet->dwIP, cur_packet->nPort)){
sentBytes += cur_packet->packet->size+2; // ZZ:UploadBandWithThrottler (UDP)
controlpacket_queue.RemoveHead();
delete cur_packet->packet;
delete cur_packet;
}
delete[] sendbuffer;
}
else
{
controlpacket_queue.RemoveHead();
delete cur_packet->packet;
delete cur_packet;
}
}
// ZZ:UploadBandWithThrottler (UDP) -->
if(!IsBusy() && !controlpacket_queue.IsEmpty()) {
theApp.uploadBandwidthThrottler->QueueForSendingControlPacket(this);
}
sendLocker.Unlock();
SocketSentBytes returnVal = { true, 0, sentBytes };
return returnVal;
// <-- ZZ:UploadBandWithThrottler (UDP)
}
int CClientUDPSocket::SendTo(char* lpBuf,int nBufLen,uint32 dwIP, uint16 nPort){
// NOTE: *** This function is invoked from a *different* thread!
uint32 result = CAsyncSocket::SendTo(lpBuf,nBufLen,nPort,ipstr(dwIP));
if (result == (uint32)SOCKET_ERROR){
uint32 error = GetLastError();
if (error == WSAEWOULDBLOCK){
m_bWouldBlock = true;
return -1;
}
if (thePrefs.GetVerbose())
theApp.QueueDebugLogLine(false, _T("Error: Client UDP socket, failed to send data to %s:%u: %s"), ipstr(dwIP), nPort, GetErrorMessage(error, 1));
}
return 0;
}
bool CClientUDPSocket::SendPacket(Packet* packet, uint32 dwIP, uint16 nPort){
UDPPack* newpending = new UDPPack;
newpending->dwIP = dwIP;
newpending->nPort = nPort;
newpending->packet = packet;
newpending->dwTime = GetTickCount();
// ZZ:UploadBandWithThrottler (UDP) -->
sendLocker.Lock();
controlpacket_queue.AddTail(newpending);
sendLocker.Unlock();
theApp.uploadBandwidthThrottler->QueueForSendingControlPacket(this);
return true;
// <-- ZZ:UploadBandWithThrottler (UDP)
}
bool CClientUDPSocket::Create(){
bool ret=true;
if (thePrefs.GetUDPPort()) {
ret=CAsyncSocket::Create(thePrefs.GetUDPPort(),SOCK_DGRAM,FD_READ|FD_WRITE);
if (ret) {
m_port=thePrefs.GetUDPPort();
if (thePrefs.GetUPnPNat()){
CUPnPNat::UPNPNAT_MAPPING mapping;
mapping.internalPort = mapping.externalPort = thePrefs.GetUDPPort();
mapping.protocol = CUPnPNat::UNAT_UDP;
mapping.description = "UDP Port";
if (theApp.AddUPnPNatPort(&mapping, thePrefs.GetUPnPNatTryRandom()))
thePrefs.SetUPnPUDPExternal(mapping.externalPort);
}
else{
thePrefs.SetUPnPUDPExternal(thePrefs.GetUDPPort());
}
return true;
}
else
return false;
}
// VeryCD版
if (ret)
m_port=thePrefs.GetUDPPort();
return ret;
}
bool CClientUDPSocket::Rebind(){
if (thePrefs.GetUDPPort()==m_port)
return false;
Close();
return Create();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -