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 :