📄 listensocket.cpp
字号:
case OP_QUEUERANKING:{
theApp.downloadqueue->AddDownDataOverheadOther(size);
if (size != 12)
throw GetResString(IDS_ERR_BADSIZE);
uint16 newrank;
memcpy(&newrank,packet+0,2);
client->SetRemoteQueueFull(false);
client->SetRemoteQueueRank(newrank);
break;
}
case OP_REQUESTSOURCES:{
theApp.downloadqueue->AddDownDataOverheadSourceExchange(size);
if (client->GetSourceExchangeVersion() >= 1){
if(size != 16)
throw GetResString(IDS_ERR_BADSIZE);
//first check shared file list, then download list
CKnownFile* file = theApp.sharedfiles->GetFileByID((uchar*)packet);
if(!file)
file = theApp.downloadqueue->GetFileByID((uchar*)packet);
if(file) {
DWORD dwTimePassed = ::GetTickCount() - client->GetLastSrcReqTime() + CONNECTION_LATENCY;
bool bNeverAskedBefore = client->GetLastSrcReqTime() == 0;
if(
//if not complete and file is rare, allow once every 10 minutes
( file->IsPartFile() &&
((CPartFile*)file)->GetSourceCount() <= RARE_FILE * 2 &&
(bNeverAskedBefore || dwTimePassed > SOURCECLIENTREASK)
) ||
//OR if file is not rare or if file is complete, allow every 90 minutes
( (bNeverAskedBefore || dwTimePassed > SOURCECLIENTREASK * MINCOMMONPENALTY) )
) {
client->SetLastSrcReqTime();
Packet* tosend = file->CreateSrcInfoPacket(client);
if(tosend){
theApp.uploadqueue->AddUpDataOverheadSourceExchange(tosend->size);
SendPacket(tosend, true, true);
theApp.emuledlg->AddDebugLogLine( false, "RCV:Source Request User(%s) File(%s)", client->GetUserName(), file->GetFileName() );
}
}
}
}
break;
}
case OP_ANSWERSOURCES:{
theApp.downloadqueue->AddDownDataOverheadSourceExchange(size);
try{
CSafeMemFile data((BYTE*)packet,size);
uchar hash[16];
data.Read(hash,16);
CKnownFile* file = theApp.downloadqueue->GetFileByID((uchar*)packet);
if(file){
if (file->IsPartFile()){
//set the client's answer time
client->SetLastSrcAnswerTime();
//and set the file's last answer time
((CPartFile*)file)->SetLastAnsweredTime();
((CPartFile*)file)->AddClientSources(&data, client->GetSourceExchangeVersion());
}
}
}
catch(CFileException* error){
OUTPUT_DEBUG_TRACE();
error->Delete();
throw GetResString(IDS_ERR_INVALIDPACKAGE);
}
break;
}
case OP_FILEDESC:{
theApp.downloadqueue->AddDownDataOverheadOther(size);
client->ProcessMuleCommentPacket(packet,size);
break;
}
/*case OP_VERIFYUPSREQ:{
CUpDownClient* vuclient = theApp.clientlist->VUGetRandomClient();
if (vuclient){
Packet* answer = new Packet(OP_VERIFYUPSANSWER,6,OP_EMULEPROT);
uint32 ip = vuclient->GetIP();
memcpy(answer->pBuffer,ip,4);
uint16 udpport = vuclient->GetUDPPort();
memcpy(answer->pBuffer,ip,4);
theApp.uploadqueue->AddUpDataRateMSOverhead(packet->size);
SendPacket(answer,true,true);
}
}
case OP_VERIFYUPSANSWER:{
if (size != 12)
throw CString("invalid size (OP_VERIFYUPSANSWER)");
}*/
default:
theApp.downloadqueue->AddDownDataOverheadOther(size);
theApp.emuledlg->AddDebugLogLine(false,"unknown opcode: %i %x",opcode,opcode);
}
}
catch(CString error){
OUTPUT_DEBUG_TRACE();
theApp.emuledlg->AddDebugLogLine(false,GetResString(IDS_ERR_BADCLIENTACTION),error.GetBuffer());
if (client) client->SetDownloadState(DS_ERROR);
Disconnect();
return false;
}
return true;
}
void CClientReqSocket::OnInit(){
uint8 tv = 1;
//SetSockOpt(SO_DONTLINGER,&tv,sizeof(BOOL));
}
void CClientReqSocket::OnSend(int nErrorCode){
ResetTimeOutTimer();
CEMSocket::OnSend(nErrorCode);
}
void CClientReqSocket::OnError(int nErrorCode){
if (client)
theApp.emuledlg->AddDebugLogLine(false,GetResString(IDS_ERR_BADCLIENT2)
,client->GetUserName(),client->GetFullIP(),nErrorCode);
else
theApp.emuledlg->AddDebugLogLine(false,GetResString(IDS_ERR_BADCLIENTACTION),"CClientReqSocket::OnError");
Disconnect();
}
void CClientReqSocket::PacketReceived(Packet* packet){
switch (packet->prot){
case OP_EDONKEYPROT:
ProcessPacket(packet->pBuffer,packet->size,packet->opcode);
break;
case OP_PACKEDPROT:
if (!packet->UnPackPacket()){
ASSERT ( false );
break;
}
case OP_EMULEPROT:
ProcessExtPacket(packet->pBuffer,packet->size,packet->opcode);
break;
default:;
}
}
void CClientReqSocket::OnReceive(int nErrorCode){
ResetTimeOutTimer();
CEMSocket::OnReceive(nErrorCode);
}
bool CClientReqSocket::Create(){
theApp.listensocket->AddConnection();
BOOL result = CAsyncSocket::Create(0,SOCK_STREAM,FD_WRITE|FD_READ|FD_CLOSE);
OnInit();
return result;
}
// CListenSocket
// CListenSocket member functions
CListenSocket::CListenSocket(CPreferences* in_prefs){
app_prefs = in_prefs;
opensockets = 0;
maxconnectionreached = 0;
m_OpenSocketsInterval = 0;
m_nPeningConnections = 0;
}
CListenSocket::~CListenSocket(){
Close();
KillAllSockets();
}
bool CListenSocket::StartListening(){
bListening = true;
return (this->Create(app_prefs->GetPort(),SOCK_STREAM,FD_ACCEPT) && this->Listen());
}
void CListenSocket::ReStartListening(){
bListening = true;
if (m_nPeningConnections){
m_nPeningConnections--;
OnAccept(0);
}
}
void CListenSocket::StopListening(){
bListening = false;
maxconnectionreached++;
}
void CListenSocket::OnAccept(int nErrorCode){
if (!nErrorCode){
m_nPeningConnections++;
if (m_nPeningConnections < 1){
ASSERT ( false );
m_nPeningConnections = 1;
}
if (TooManySockets(true) && !theApp.serverconnect->IsConnecting()){
StopListening();
return;
}
else if ( bListening == false )
ReStartListening(); //If the client is still at maxconnections, this will allow it to go above it.. But if you don't, you will get a lowID on all servers.
while (m_nPeningConnections){
m_nPeningConnections--;
CClientReqSocket* newclient = new CClientReqSocket(app_prefs);
if (!Accept(*newclient))
newclient->Safe_Delete();
else{
newclient->AsyncSelect(FD_WRITE|FD_READ|FD_CLOSE);
newclient->OnInit();
}
AddConnection();
}
// if (TooManySockets(true) && !theApp.serverconnect->IsConnecting())
// StopListening();
}
}
void CListenSocket::Process(){
POSITION pos2;
m_OpenSocketsInterval = 0;
opensockets = 0;
for(POSITION pos1 = socket_list.GetHeadPosition(); ( pos2 = pos1 ) != NULL; ){
socket_list.GetNext(pos1);
CClientReqSocket* cur_sock = socket_list.GetAt(pos2);
opensockets++;
if (cur_sock->deletethis){
if (cur_sock->m_hSocket != INVALID_SOCKET){
cur_sock->Close();
}
else{
cur_sock->Delete_Timed();;
}
}
else
socket_list.GetAt( pos2 )->CheckTimeOut();
}
if ( (GetOpenSockets()+5 < app_prefs->GetMaxConnections() || theApp.serverconnect->IsConnecting()) && !bListening)
ReStartListening();
}
void CListenSocket::RecalculateStats(){
memset(m_ConnectionStates,0,6);
POSITION pos1,pos2;
for(pos1 = socket_list.GetHeadPosition(); ( pos2 = pos1 ) != NULL; ){
socket_list.GetNext(pos1);
CClientReqSocket* cur_sock = socket_list.GetAt(pos2);
switch (cur_sock->GetConState()){
case ES_DISCONNECTED:
m_ConnectionStates[0]++;
break;
case ES_NOTCONNECTED:
m_ConnectionStates[1]++;
break;
case ES_CONNECTED:
m_ConnectionStates[2]++;
break;
}
}
}
void CListenSocket::AddSocket(CClientReqSocket* toadd){
socket_list.AddTail(toadd);
}
void CListenSocket::RemoveSocket(CClientReqSocket* todel){
POSITION pos2,pos1;
for(pos1 = socket_list.GetHeadPosition(); ( pos2 = pos1 ) != NULL; ){
socket_list.GetNext(pos1);
if ( socket_list.GetAt(pos2) == todel )
socket_list.RemoveAt(pos2);
}
}
void CListenSocket::KillAllSockets(){
for (POSITION pos = socket_list.GetHeadPosition();pos != 0;pos = socket_list.GetHeadPosition()){
CClientReqSocket* cur_socket = socket_list.GetAt(pos);
if (cur_socket->client)
delete cur_socket->client;
else
delete cur_socket;
}
}
void CListenSocket::AddConnection(){
m_OpenSocketsInterval++;
opensockets++;
}
bool CListenSocket::TooManySockets(bool bIgnoreInterval){
if (GetOpenSockets() > app_prefs->GetMaxConnections() || (m_OpenSocketsInterval > (theApp.glob_prefs->GetMaxConperFive()*theApp.emuledlg->statisticswnd.GetMaxConperFiveModifier()) && !bIgnoreInterval) ){
return true;
}
else
return false;
}
bool CListenSocket::IsValidSocket(CClientReqSocket* totest){
return socket_list.Find(totest);
}
void CListenSocket::Debug_ClientDeleted(CUpDownClient* deleted){
POSITION pos1, pos2;
for (pos1 = socket_list.GetHeadPosition();( pos2 = pos1 ) != NULL;){
socket_list.GetNext(pos1);
CClientReqSocket* cur_sock = socket_list.GetAt(pos2);
if (!AfxIsValidAddress(cur_sock, sizeof(CClientReqSocket))) {
AfxDebugBreak();
}
if (cur_sock->client == deleted){
AfxDebugBreak();
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -