DWORD WINAPI CClientManager::ThreadConn(LPVOID lp) { AUTO_LOG_FUNCTION; CClientManager* manager = reinterpret_cast<CClientManager*>(lp); for (;;) { if (WAIT_OBJECT_0 == WaitForSingleObject(manager->m_hEventShutdown, 1)) break; if (manager->m_bShuttingDown) { break; } for (auto client_iter : manager->m_client_map) { if (WAIT_OBJECT_0 == WaitForSingleObject(manager->m_hEventShutdown, 1)) break; if (manager->m_bShuttingDown) { break; } auto client = client_iter.second; if (!client->IsConnectionEstablished()) { if (client->Connect(manager->m_server_ip, manager->m_server_port)) { manager->m_handler->OnConnectionEstablished(client); } else { continue; } } } } return 0; }
BOOL HandleCopyData(HWND hwndSrc, PCOPYDATASTRUCT pcds) { if (!pcds || !IsConnectionEstablished()) return FALSE; // client -> skype if (hwndSrc == _hwndClient) { _msgCntIn++; return SendMessage(_hwndSkype, WM_COPYDATA, (WPARAM)_hwnd, (LPARAM)pcds); } // skype -> client if (hwndSrc == _hwndSkype) { _msgCntOut++; return SendMessage(_hwndClient, WM_COPYDATA, (WPARAM)_hwnd, (LPARAM)pcds); } return FALSE; }
DWORD WINAPI CClientManager::ThreadWorker(LPVOID lp) { AUTO_LOG_FUNCTION; CClientManager* manager = reinterpret_cast<CClientManager*>(lp); timeval tv = { 0, 10 }; DWORD dwCount = 0; for (;;) { dwCount++; if (WAIT_OBJECT_0 == WaitForSingleObject(manager->m_hEventShutdown, 1)) break; if (manager->m_bShuttingDown) { break; } for (auto client_iter : manager->m_client_map) { if (WAIT_OBJECT_0 == WaitForSingleObject(manager->m_hEventShutdown, 0)) break; if (manager->m_bShuttingDown) { break; } auto client = client_iter.second; if (!client->IsConnectionEstablished()) { continue; } int nRet = 0; fd_set fdRead, fdWrite; FD_ZERO(&fdRead); FD_ZERO(&fdWrite); FD_SET(client->m_socket, &fdRead); FD_SET(client->m_socket, &fdWrite); nRet = select(client->m_socket + 1, &fdRead, &fdWrite, nullptr, &tv); if (WAIT_OBJECT_0 == WaitForSingleObject(manager->m_hEventShutdown, 0)) continue; BOOL bRead = FD_ISSET(client->m_socket, &fdRead); BOOL bWrite = FD_ISSET(client->m_socket, &fdWrite); if (bRead) { char* temp = client->m_buff.buff + client->m_buff.wpos; DWORD dwLenToRead = BUFF_SIZE - client->m_buff.wpos; nRet = recv(client->m_socket, temp, dwLenToRead, 0); if (nRet <= 0) { JLOG(_T("ThreadRecv::recv ret <= 0, ret %d"), nRet); manager->m_handler->OnConnectionLost(client); client->Disconnect(); continue; } else if (manager->m_handler) { client->m_buff.wpos += nRet; DWORD ret = RESULT_OK; ret = manager->m_handler->OnRecv(client); while (1) { unsigned int bytes_not_commited = client->m_buff.wpos - client->m_buff.rpos; if (bytes_not_commited == 0) { if (client->m_buff.wpos == BUFF_SIZE) { client->m_buff.Clear(); } break; } if (client->m_buff.wpos == BUFF_SIZE) { memmove_s(client->m_buff.buff, BUFF_SIZE, client->m_buff.buff + client->m_buff.rpos, bytes_not_commited); memset(client->m_buff.buff + bytes_not_commited, 0, BUFF_SIZE - bytes_not_commited); client->m_buff.wpos -= client->m_buff.rpos; client->m_buff.rpos = 0; ret = manager->m_handler->OnRecv(client); } else { ret = manager->m_handler->OnRecv(client); } if (ret == RESULT_NOT_ENOUGH) { break; } } client->last_recv_time_ = COleDateTime::GetTickCount(); } } if (bWrite) { // send link test if (manager->m_handler && client->m_bConnectionEstablished && ((COleDateTime::GetTickCount() - client->last_send_link_test_time_).GetTotalSeconds() * 1000 >= LINK_TEST_GAP)) { char buff[4096] = { 0 }; DWORD dwLen = client->GenerateLinkTestPackage(buff, sizeof(buff)); if (dwLen > 0 && dwLen <= sizeof(buff)) { int nLen = client->Send(buff, dwLen); if (nLen <= 0) { JLOG(_T("ThreadLinkTest::Send ret <= 0, ret %d"), nLen); client->Disconnect(); manager->m_handler->OnConnectionLost(client); continue; } CWinApp* app = AfxGetApp(); if (app) { CWnd* wnd = app->GetMainWnd(); if (wnd) { wnd->PostMessageW(WM_NETWORKSTARTUPOK, mp_snd_lnk_tst, client->get_acct_id()); } } JLOG(_T("Send link test to transmite server, len %d\n"), nLen); client->last_send_link_test_time_ = COleDateTime::GetTickCount(); } } // send data if (!client->buffer_.empty() && client->buffer_lock_.try_lock()) { std::lock_guard<std::mutex> lock(client->buffer_lock_, std::adopt_lock); auto buffer = client->buffer_.front(); client->Send(&buffer[0], buffer.size()); client->buffer_.pop_front(); } } // check timeup /*if (dwCount % 1000 == 0) { dwCount = 0; if ((COleDateTime::GetTickCount() - client->last_recv_time_).GetTotalSeconds() * 1000 > LINK_TEST_GAP * 3) { manager->m_handler->OnConnectionLost(client); client->Disconnect(); } }*/ } } return 0; }