⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 listensocket.cpp

📁 非常出名开源客户端下载的程序emule
💻 CPP
📖 第 1 页 / 共 3 页
字号:
//this file is part of eMule
//Copyright (C)2002 Merkur ( merkur-@users.sourceforge.net / http://www.emule-project.net )
//
//This program is free software; you can redistribute it and/or
//modify it under the terms of the GNU General Public License
//as published by the Free Software Foundation; either
//version 2 of the License, or (at your option) any later version.
//
//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//GNU General Public License for more details.
//
//You should have received a copy of the GNU General Public License
//along with this program; if not, write to the Free Software
//Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
// ListenSocket.cpp : implementation file
//

#include "stdafx.h"
#include "emule.h"
#include "ListenSocket.h"
#include "opcodes.h"
#include "KnownFile.h"
#include "sharedfilelist.h"
#include "uploadqueue.h"
#include "updownclient.h"
#include "clientlist.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif


// CClientReqSocket
CClientReqSocket::CClientReqSocket(CPreferences* in_prefs,CUpDownClient* in_client){
	app_prefs = in_prefs;
	client = in_client;
	if (in_client)
		client->socket = this;
	theApp.listensocket->AddSocket(this);
	ResetTimeOutTimer();
	deletethis = false;
	deltimer = 0;
}


CClientReqSocket::~CClientReqSocket(){
	if (client)
		client->socket = 0;
	client = 0;
	theApp.listensocket->RemoveSocket(this);

	DEBUG_ONLY (theApp.clientlist->Debug_SocketDeleted(this));
}

void CClientReqSocket::ResetTimeOutTimer(){
	timeout_timer = ::GetTickCount();
};

bool CClientReqSocket::CheckTimeOut(){
	if (::GetTickCount() - timeout_timer > CONNECTION_TIMEOUT){
		timeout_timer = ::GetTickCount();
		Disconnect();
		return true;
	}
	return false;
};

void CClientReqSocket::OnClose(int nErrorCode){
	ASSERT (theApp.listensocket->IsValidSocket(this));
	CEMSocket::OnClose(nErrorCode);
	Disconnect();
};

void CClientReqSocket::Disconnect(){
	AsyncSelect(0);
	byConnected = ES_DISCONNECTED;
	if (!client)
		Safe_Delete();
	else
		client->Disconnected();
};

void CClientReqSocket::Delete_Timed(){
// it seems that MFC Sockets call socketfunctions after they are deleted, even if the socket is closed
// and select(0) is set. So we need to wait some time to make sure this doesn't happens
	if (::GetTickCount() - deltimer > 10000)
		delete this;
}

void CClientReqSocket::Safe_Delete(){
	ASSERT (theApp.listensocket->IsValidSocket(this));
	AsyncSelect(0);
	deltimer = ::GetTickCount();
	if (m_hSocket != INVALID_SOCKET)
		ShutDown(2);
	if (client)
		client->socket = 0;
	client = 0;
	byConnected = ES_DISCONNECTED;
	deletethis = true;
}

bool CClientReqSocket::ProcessPacket(char* packet, uint32 size, uint8 opcode){
	try{
		try{
			if (!client && opcode != OP_HELLO)
				throw GetResString(IDS_ERR_NOHELLO);
			switch(opcode){
				case OP_HELLOANSWER:{
					theApp.downloadqueue->AddDownDataOverheadOther(size);
					client->ProcessHelloAnswer(packet,size);
					if (client){
						client->ConnectionEstablished();
						theApp.emuledlg->transferwnd.clientlistctrl.RefreshClient(client);
					}
					break;
				}
				case OP_HELLO:{
					theApp.downloadqueue->AddDownDataOverheadOther(size);
					if (!client){
						// create new client to save standart informations
						client = new CUpDownClient(this);
					}
					client->ProcessHelloPacket(packet,size);
					// now we check if we now this client already. if yes this socket will
					// be attached to the known client, the new client will be deleted
					// and the var. "client" will point to the known client.
					// if not we keep our new-constructed client ;)
					if (theApp.clientlist->AttachToAlreadyKnown(&client,this)){
						// update the old client informations
						client->ProcessHelloPacket(packet,size);
					}
					else {
						theApp.clientlist->AddClient(client);
						client->SetCommentDirty();
					}
					
					theApp.emuledlg->transferwnd.clientlistctrl.RefreshClient(client);

					// if IP is filtered, dont reply but disconnect...
					if (theApp.ipfilter->IsFiltered(client->GetIP())) {
						theApp.emuledlg->AddDebugLogLine(true,GetResString(IDS_IPFILTERED),client->GetFullIP(),theApp.ipfilter->GetLastHit());
						client->Disconnected();
						theApp.stat_filteredclients++;
						break;
					}

					// send a response packet with standart informations
					if (client->GetClientSoft() == SO_EMULE )
						client->SendMuleInfoPacket(false);
					
					client->SendHelloAnswer();
					if (client)
						client->ConnectionEstablished();

					break;
				}
				case OP_FILEREQUEST:{
					theApp.downloadqueue->AddDownDataOverheadFileRequest(size);
					if (size == 16 || (size > 16 && client->GetExtendedRequestsVersion() > 0)){
						if (!client->GetWaitStartTime())
							client->SetWaitStartTime();
						uchar reqfileid[16];
						memcpy(reqfileid,packet,16);
						CKnownFile* reqfile = theApp.sharedfiles->GetFileByID(reqfileid);
						if (!reqfile){
							// DbT:FileRequest
							// send file request no such file packet (0x48)
							Packet* replypacket = new Packet(OP_FILEREQANSNOFIL, 16);
							memcpy(replypacket->pBuffer, packet, 16);
							theApp.uploadqueue->AddUpDataOverheadFileRequest(replypacket->size);
							SendPacket(replypacket, true);
							// DbT:End
							break;
						}
						// if wer are downloading this file, this could be a new source
						if (reqfile->IsPartFile())
							if( theApp.glob_prefs->GetMaxSourcePerFile() > ((CPartFile*)reqfile)->GetSourceCount() ) //<<--
								theApp.downloadqueue->CheckAndAddKnownSource((CPartFile*)reqfile,client);
						
						// check to see if this is a new file they are asking for
						if(memcmp(client->GetUploadFileID(), packet, 16) != 0)
							client->SetCommentDirty();

//						CKnownFile* clientreqfile = theApp.sharedfiles->GetFileByID(client->GetUploadFileID());
//						if( clientreqfile )
//							clientreqfile->SubQueuedCount();
//						reqfile->AddQueuedCount();
						// send filename etc
						client->SetUploadFileID((uchar*)packet);
//						memcpy(client->reqfileid,packet,16);
						CMemFile* data = new CMemFile();
						data->Write(reqfile->GetFileHash(),16);
						uint16 namelength = (uint16)strlen(reqfile->GetFileName());
						data->Write(&namelength,2);
						data->Write(reqfile->GetFileName(),namelength);
						client->ProcessUpFileStatus(packet,size);
						Packet* packet = new Packet(data);
						packet->opcode = OP_FILEREQANSWER;
						delete data;
						theApp.uploadqueue->AddUpDataOverheadFileRequest(packet->size);
						SendPacket(packet,true);
						/* done with "OP_SETREQFILEID" now
						//send filestatus 
						data = new CMemFile();
						data->Write(reqfile->GetFileHash(),16);
						if (reqfile->IsPartFile())
							((CPartFile*)reqfile)->WritePartStatus(data);
						else{
							uint32 null = 0;
							data->Write(&null,3);
						}
						packet = new Packet(data);
						packet->opcode = OP_FILESTATUS;
						delete data;
						theApp.uploadqueue->AddUpDataOverheadFileRequest(packet->size);
						SendPacket(packet,true);
						*/
						client->SendCommentInfo(reqfile);
						break;
					}
					throw GetResString(IDS_ERR_WRONGPACKAGESIZE);
					break;
				}
				case OP_FILEREQANSNOFIL:{
					theApp.downloadqueue->AddDownDataOverheadFileRequest(size);
				// DbT:FileRequest
				if (size == 16) {
					// if that client do not have my file maybe has another different
					CPartFile* reqfile = theApp.downloadqueue->GetFileByID((uchar*)packet);
					if (!reqfile)
						break;

					// we try to swap to another file ignoring no needed parts files
					if (client) switch (client->GetDownloadState()) {
						case DS_ONQUEUE:
						case DS_NONEEDEDPARTS:
						if (!client->SwapToAnotherFile(false)) {
							theApp.downloadqueue->RemoveSource(client, true);
						}
						break;
					}
					break;
				}
				throw GetResString(IDS_ERR_WRONGPACKAGESIZE);
				break;
				// DbT:End
				}
				case OP_FILEREQANSWER:{
					theApp.downloadqueue->AddDownDataOverheadFileRequest(size);
					client->ProcessFileInfo(packet,size);
					break;
				}
				case OP_FILESTATUS:{
					theApp.downloadqueue->AddDownDataOverheadFileRequest(size);
					client->ProcessFileStatus(packet,size);
					break;
				}
				case OP_STARTUPLOADREQ:{
					theApp.downloadqueue->AddDownDataOverheadFileRequest(size);
					if( size == 16 ){
						uchar reqfileid[16];
						memcpy(reqfileid,packet,16);
						CKnownFile* reqfile = theApp.sharedfiles->GetFileByID(reqfileid);
						if (reqfile){
							if (reqfile->IsPartFile())
								if( theApp.glob_prefs->GetMaxSourcePerFile() > ((CPartFile*)reqfile)->GetSourceCount() ) //<<--
									theApp.downloadqueue->CheckAndAddKnownSource((CPartFile*)reqfile,client);
							if(memcmp(client->GetUploadFileID(), packet, 16) != 0)
								client->SetCommentDirty();
							client->SetUploadFileID((uchar*)packet);
							client->SendCommentInfo(reqfile);
						}
					}
					theApp.uploadqueue->AddClientToQueue(client);
					break;
				}
				case OP_QUEUERANK:{
					theApp.downloadqueue->AddDownDataOverheadFileRequest(size);
					CSafeMemFile* data = new CSafeMemFile((BYTE*)packet,size);
					uint32 rank;
					data->Read(&rank,4);
					client->SetRemoteQueueRank(rank);
					delete data;
					break;
				}
				case OP_ACCEPTUPLOADREQ:{
					theApp.downloadqueue->AddDownDataOverheadFileRequest(size);
					if (client->GetDownloadState() == DS_ONQUEUE ){
						client->SetDownloadState(DS_DOWNLOADING);
						client->SendBlockRequests();
					}
					break;
				}
				case OP_REQUESTPARTS:{
					theApp.downloadqueue->AddDownDataOverheadFileRequest(size);
					CSafeMemFile* data = new CSafeMemFile((BYTE*)packet,size);
					uchar reqfilehash[16];
					data->Read(reqfilehash,16);
					Requested_Block_Struct* reqblock1 = new Requested_Block_Struct;
					Requested_Block_Struct* reqblock2 = new Requested_Block_Struct;
					Requested_Block_Struct* reqblock3 = new Requested_Block_Struct;
					data->Read(&reqblock1->StartOffset,4);
					data->Read(&reqblock2->StartOffset,4);
					data->Read(&reqblock3->StartOffset,4);
					data->Read(&reqblock1->EndOffset,4);
					data->Read(&reqblock2->EndOffset,4);
					data->Read(&reqblock3->EndOffset,4);
					memcpy(&reqblock1->FileID,reqfilehash,16);
					memcpy(&reqblock2->FileID,reqfilehash,16);
					memcpy(&reqblock3->FileID,reqfilehash,16);
					if (reqblock1->EndOffset-reqblock1->StartOffset == 0)			
						delete reqblock1;
					else
						client->AddReqBlock(reqblock1);

					if (reqblock2->EndOffset-reqblock2->StartOffset == 0)			
						delete reqblock2;
					else
						client->AddReqBlock(reqblock2);

					if (reqblock3->EndOffset-reqblock3->StartOffset == 0)			
						delete reqblock3;
					else
						client->AddReqBlock(reqblock3);
					delete data;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -