C++ for Simultaneous TLS or Plain Socket Read/Write from Different Threads (Windows)
#if defined(WIN32) static int _numSockThreadsRunning = 0; static bool _bTlsConnection = false; static DWORD WINAPI SockThreadA(LPVOID lpvThreadParm) { CkSocket *pSock0 = (CkSocket *)lpvThreadParm; CkSocket *pSock = pSock0->CloneSocket(); // Read the HTTP response header. while (true) { CkString strLine; bool success = pSock->ReceiveToCRLF(strLine); if (!success) { printf("%s\n",pSock->lastErrorText()); break; } printf("Received: %s",strLine.getString()); if (strLine.equals("\r\n")) break; // We have the full header.. } delete pSock; _numSockThreadsRunning--; return 0; } static DWORD WINAPI SockThreadB(LPVOID lpvThreadParm) { CkSocket *pSock0 = (CkSocket *)lpvThreadParm; CkSocket *pSock = pSock0->CloneSocket(); while (_numSockThreadsRunning > 1) { DWORD startTick = GetTickCount(); bool bConnected = pSock->get_IsConnected(); DWORD endTick = GetTickCount(); if ((endTick - startTick) > 500) { printf("ERROR -- IsConnected blocked.\n"); break; } printf("bConnected: %d\n",bConnected); Sleep(200); } delete pSock; _numSockThreadsRunning--; return 0; } static DWORD WINAPI SockThreadC(LPVOID lpvThreadParm) { CkSocket *pSock0 = (CkSocket *)lpvThreadParm; CkSocket *pSock = pSock0->CloneSocket(); // Wait 3 seconds, and then send the GET request.. // The socket read in thread A should not be blocking the IsConnected calls. Sleep(3000); CkString strGet; if (_bTlsConnection) { pSock->BuildHttpGetRequest("https://www.chilkatsoft.com/test.asp",strGet); } else { pSock->BuildHttpGetRequest("http://www.chilkatsoft.com/test.asp",strGet); } bool success = pSock->SendString(strGet.getString()); if (!success) { printf("%s\n",pSock->lastErrorText()); } delete pSock; _numSockThreadsRunning--; return 0; } static bool startSockThread(char which, CkSocket *pSock) { bool success = false; DWORD threadID; HANDLE hThread = NULL; if (which == 'A') hThread = CreateThread(0,0,SockThreadA,(void *)pSock,0,&threadID); if (which == 'B') hThread = CreateThread(0,0,SockThreadB,(void *)pSock,0,&threadID); if (which == 'C') hThread = CreateThread(0,0,SockThreadC,(void *)pSock,0,&threadID); if (hThread != NULL) { CloseHandle(hThread); success = true; _numSockThreadsRunning++; } return success; } bool SocketTesting::qa_simultaneousMtReadWrite(bool bTls) { CkSocket sock; _bTlsConnection = bTls; sock.put_VerboseLogging(true); //sock.put_DebugLogFilePath("c:/aaworkarea/debugLogPath.txt"); bool success = false; if (bTls) { success = sock.Connect("www.chilkatsoft.com",443,true,5000); } else { success = sock.Connect("www.chilkatsoft.com",80,false,5000); } if (!success) { printf("%s\n",sock.lastErrorText()); printf("qa_simultaneousMtReadWrite failed\n"); return false; } success = startSockThread('A',&sock); if (success) success = startSockThread('B',&sock); if (success) success = startSockThread('C',&sock); if (!success) { printf("Failed to start threads.\n"); printf("qa_simultaneousMtReadWrite failed\n"); return false; } int loopCount = 0; while (_numSockThreadsRunning) { Sleep(100); loopCount++; if (loopCount > 200) { // It shouldn't take this long... printf("qa_simultaneousMtReadWrite failed! TIMED OUT.\n"); return false; } } printf("loopCount = %d\n",loopCount); printf("qa_simultaneousMtReadWrite success\n"); return true; } #endif
admin
0
Tags :