📄 sockets.cpp
字号:
//messages
CServer* update;
switch (sender->GetConnectionState()){
case CS_FATALERROR:
AddLogLine(true,GetResString(IDS_ERR_FATAL));
break;
case CS_DISCONNECTED:{
theApp.sharedfiles->ClearED2KPublishInfo();
AddLogLine(true,GetResString(IDS_ERR_LOSTC),sender->cur_server->GetListName(),sender->cur_server->GetFullIP(),sender->cur_server->GetPort());
break;
}
case CS_SERVERDEAD:
AddLogLine(true,GetResString(IDS_ERR_DEAD),sender->cur_server->GetListName(),sender->cur_server->GetFullIP(),sender->cur_server->GetPort()); //<<--
update = theApp.serverlist->GetServerByAddress( sender->cur_server->GetAddress(), sender->cur_server->GetPort() );
if(update){
update->AddFailedCount();
theApp.emuledlg->serverwnd->serverlistctrl.RefreshServer( update );
}
break;
case CS_ERROR:
break;
case CS_SERVERFULL:
AddLogLine(true,GetResString(IDS_ERR_FULL),sender->cur_server->GetListName(),sender->cur_server->GetFullIP(),sender->cur_server->GetPort());
break;
case CS_NOTCONNECTED:;
break;
}
// IMPORTANT: mark this socket not to be deleted in StopConnectionTry(),
// because it will delete itself after this function!
sender->m_bIsDeleting = true;
switch (sender->GetConnectionState()){
case CS_FATALERROR:{
bool autoretry= !singleconnecting;
StopConnectionTry();
if ((thePrefs.Reconnect()) && (autoretry) && (!m_idRetryTimer)){
AddLogLine(false,GetResString(IDS_RECONNECT), CS_RETRYCONNECTTIME);
VERIFY( (m_idRetryTimer= SetTimer(NULL, 0, 1000*CS_RETRYCONNECTTIME, RetryConnectTimer)) != NULL );
if (thePrefs.GetVerbose() && !m_idRetryTimer)
AddDebugLogLine(true,_T("Failed to create 'server connect retry' timer - %s"),GetErrorMessage(GetLastError()));
}
break;
}
case CS_DISCONNECTED:{
theApp.sharedfiles->ClearED2KPublishInfo();
connected = false;
if (connectedsocket)
connectedsocket->Close();
connectedsocket = NULL;
theApp.emuledlg->searchwnd->CancelSearch();
// -khaos--+++> Tell our total server duration thinkymajig to update...
theStats.serverConnectTime = 0;
theStats.Add2TotalServerDuration();
// <-----khaos-
if (thePrefs.Reconnect() && !connecting){
ConnectToAnyServer();
}
if (thePrefs.GetNotifierPopOnImportantError()) {
theApp.emuledlg->ShowNotifier(GetResString(IDS_CONNECTIONLOST), TBN_IMPORTANTEVENT);
}
break;
}
case CS_ERROR:
case CS_NOTCONNECTED:{
if (!connecting)
break;
}
case CS_SERVERDEAD:
case CS_SERVERFULL:{
if (!connecting)
break;
if (singleconnecting){
StopConnectionTry();
break;
}
DWORD tmpkey;
CServerSocket* tmpsock;
POSITION pos = connectionattemps.GetStartPosition();
while (pos){
connectionattemps.GetNextAssoc(pos,tmpkey,tmpsock);
if (tmpsock==sender) {
connectionattemps.RemoveKey(tmpkey);
break;
}
}
TryAnotherConnectionrequest();
}
}
theApp.emuledlg->ShowConnectionState();
}
// 09/28/02, by zegzav
VOID CALLBACK CServerConnect::RetryConnectTimer(HWND hWnd, UINT nMsg, UINT nId, DWORD dwTime)
{
// NOTE: Always handle all type of MFC exceptions in TimerProcs - otherwise we'll get mem leaks
try
{
CServerConnect *_this= theApp.serverconnect;
ASSERT(_this);
_this->StopConnectionTry();
if (_this->IsConnected())
return;
_this->ConnectToAnyServer();
}
CATCH_DFLT_EXCEPTIONS(_T("CServerConnect::RetryConnectTimer"))
}
void CServerConnect::CheckForTimeout()
{
//DWORD maxage=GetTickCount() - CONSERVTIMEOUT; // this gives us problems when TickCount < TIMEOUT (may occure right after system start)
DWORD dwCurTick = GetTickCount();
DWORD tmpkey;
CServerSocket* tmpsock;
POSITION pos = connectionattemps.GetStartPosition();
while (pos){
connectionattemps.GetNextAssoc(pos,tmpkey,tmpsock);
if (!tmpsock){
if (thePrefs.GetVerbose())
AddDebugLogLine(false, _T("Error: Socket invalid at timeoutcheck"));
connectionattemps.RemoveKey(tmpkey);
return;
}
//if (tmpkey<=maxage) {
if (dwCurTick - tmpkey > CONSERVTIMEOUT){
AddLogLine(false,GetResString(IDS_ERR_CONTIMEOUT),tmpsock->cur_server->GetListName(), tmpsock->cur_server->GetFullIP(), tmpsock->cur_server->GetPort() );
connectionattemps.RemoveKey(tmpkey);
TryAnotherConnectionrequest();
DestroySocket(tmpsock);
}
}
}
bool CServerConnect::Disconnect(){
if (connected && connectedsocket){
theApp.sharedfiles->ClearED2KPublishInfo();
connected = false;
CServer* update = theApp.serverlist->GetServerByAddress( connectedsocket->cur_server->GetAddress(), connectedsocket->cur_server->GetPort() );
theApp.emuledlg->serverwnd->serverlistctrl.RefreshServer( update);
theApp.SetPublicIP(0);
DestroySocket(connectedsocket);
connectedsocket = NULL;
theApp.emuledlg->ShowConnectionState();
theApp.emuledlg->AddServerMessageLine(_T(""));
theApp.emuledlg->AddServerMessageLine(_T(""));
theApp.emuledlg->AddServerMessageLine(_T(""));
theApp.emuledlg->AddServerMessageLine(_T(""));
// -khaos--+++> Tell our total server duration thinkymajig to update...
theStats.serverConnectTime = 0;
theStats.Add2TotalServerDuration();
// <-----khaos-
return true;
}
else
return false;
}
CServerConnect::CServerConnect(CServerList* in_serverlist)
{
connectedsocket = NULL;
used_list = in_serverlist;
max_simcons = (thePrefs.IsSafeServerConnectEnabled()) ? 1 : 2;
connecting = false;
connected = false;
clientid = 0;
singleconnecting = false;
if (thePrefs.GetServerUDPPort() != 0){
udpsocket = new CUDPSocket(); // initalize socket for udp packets
if (!udpsocket->Create()){
delete udpsocket;
udpsocket = NULL;
}
}
else
udpsocket = NULL;
m_idRetryTimer= 0;
lastStartAt=0;
InitLocalIP();
}
CServerConnect::~CServerConnect(){
// stop all connections
StopConnectionTry();
// close connected socket, if any
DestroySocket(connectedsocket);
connectedsocket = NULL;
// close udp socket
if (udpsocket){
udpsocket->Close();
delete udpsocket;
}
}
CServer* CServerConnect::GetCurrentServer(){
if (IsConnected() && connectedsocket)
return connectedsocket->cur_server;
return NULL;
}
void CServerConnect::SetClientID(uint32 newid){
clientid = newid;
if (!::IsLowID(newid))
theApp.SetPublicIP(newid);
theApp.emuledlg->ShowConnectionState();
}
void CServerConnect::DestroySocket(CServerSocket* pSck){
if (pSck == NULL)
return;
// remove socket from list of opened sockets
for( POSITION pos = m_lstOpenSockets.GetHeadPosition(); pos != NULL; )
{
POSITION posDel = pos;
CServerSocket* pTestSck = (CServerSocket*)m_lstOpenSockets.GetNext(pos);
if (pTestSck == pSck)
{
m_lstOpenSockets.RemoveAt(posDel);
break;
}
}
if (pSck->m_SocketData.hSocket != INVALID_SOCKET){ // deadlake PROXYSUPPORT - changed to AsyncSocketEx
pSck->AsyncSelect(0);
pSck->Close();
}
delete pSck;
}
bool CServerConnect::IsLocalServer(uint32 dwIP, uint16 nPort){
if (IsConnected()){
if (connectedsocket->cur_server->GetIP() == dwIP && connectedsocket->cur_server->GetPort() == nPort)
return true;
}
return false;
}
void CServerConnect::InitLocalIP(){
m_nLocalIP = 0;
// Don't use 'gethostbyname(NULL)'. The winsock DLL may be replaced by a DLL from a third party
// which is not fully compatible to the original winsock DLL. ppl reported crash with SCORSOCK.DLL
// when using 'gethostbyname(NULL)'.
try{
char szHost[256];
if (gethostname(szHost, sizeof szHost) == 0){
hostent* pHostEnt = gethostbyname(szHost);
if (pHostEnt != NULL && pHostEnt->h_length == 4 && pHostEnt->h_addr_list[0] != NULL)
m_nLocalIP = *((uint32*)pHostEnt->h_addr_list[0]);
}
}
catch(...){
// at least two ppl reported crashs when using 'gethostbyname' with third party winsock DLLs
if (thePrefs.GetVerbose())
AddDebugLogLine(false, _T("Unknown exception in CServerConnect::InitLocalIP"));
ASSERT(0);
}
}
void CServerConnect::KeepConnectionAlive()
{
DWORD dwServerKeepAliveTimeout = thePrefs.GetServerKeepAliveTimeout();
if (dwServerKeepAliveTimeout && connected && connectedsocket && connectedsocket->connectionstate == CS_CONNECTED &&
GetTickCount() - connectedsocket->GetLastTransmission() >= dwServerKeepAliveTimeout)
{
// "Ping" the server if the TCP connection was not used for the specified interval with
// an empty publish files packet -> recommended by lugdunummaster himself!
CSafeMemFile files(4);
files.WriteUInt32(0); // nr. of files
Packet* packet = new Packet(&files);
packet->opcode = OP_OFFERFILES;
if (thePrefs.GetVerbose())
AddDebugLogLine(false, _T("Refreshing server connection"));
if (thePrefs.GetDebugServerTCPLevel() > 0)
Debug(_T(">>> Sending OP__OfferFiles(KeepAlive) to server\n"));
theStats.AddUpDataOverheadServer(packet->size);
connectedsocket->SendPacket(packet,true);
}
}
bool CServerConnect::IsLowID()
{
return ::IsLowID(clientid);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -