1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
| void ClientFunc(LPVOID lpParameter)
{
int idx = (int)lpParameter;
TCHAR buf[255];
SOCKET sock = gcf.clientStruct[idx].sd;
//init to minimum expected = message size = 1 int
gcf.clientStruct[idx].nDataIn = sizeof(int);
int nBytesReceived = 0;
bool bReadLength = true; // flag to switch between reading data length and data itself
gcf.clientStruct[idx].nDataOut = 0;
gcf.clientStruct[idx].bSend = false;
// Thread is effectively started
gcf.clientStruct[idx].bClientStopped = false;
// Main Loop
while (gcf.clientStruct[idx].bClientRunning){
// IN buffer handling ----------------------------------------------------------------------
//EnterCriticalSection(&critIN);
int nRead = 0;
//Sleep(50);
if (nBytesReceived < gcf.clientStruct[idx].nDataIn){// need to read
// read incoming buffer
nRead = recv(sock,(char*)gcf.clientStruct[idx].inbufferData,gcf.clientStruct[idx].nDataIn,0);
if (nRead > 0){// data was effectively read
nBytesReceived += nRead;
if (nBytesReceived == gcf.clientStruct[idx].nDataIn){// data correctly received
if (bReadLength){// the message size was received
// prepare for message body
gcf.clientStruct[idx].nDataIn = (int) ntohl( *((int*)gcf.clientStruct[idx].inbufferData) );
nBytesReceived = 0;
}// end received message size
else{// received message body
ProcessMessage(nBytesReceived, idx);
gcf.clientStruct[idx].nDataIn = sizeof(int);
nBytesReceived = 0;
}// end message body
// switch between length and data
bReadLength = !bReadLength;
}// end data correctly received
}// end data has been read
else{// error occurred
DWORD err = GetLastError();
if (err != WSAEWOULDBLOCK){
//sprintf_s(buf,255,"Client thread %d network error : %d",idx,err);
gcf.log(buf);
// "real" error - cancel
if (err == WSAECONNRESET){
// Client connection terminated
gcf.clientStruct[idx].bSend = false;
gcf.clientStruct[idx].clientThreadID = 0;
gcf.clientStruct[idx].index = -1;
gcf.clientStruct[idx].bClientRunning = false;
gcf.nClientsNb--;
closesocket(gcf.clientStruct[idx].sd);
swprintf_s(buf,255,_T("Client connection %d terminated (receiving)"),idx);
gcf.log(buf);
}
//nBytesReceived = gcf.clientStruct[idx].nDataIn;
}// end != wouldblock
}// end error occured
}// end reading
//LeaveCriticalSection(&critIN);
// OUT buffer handling ---------------------------------------------------------------------
//EnterCriticalSection(&critOUT);
if (gcf.clientStruct[idx].bSend){// There is something to send
int nBytesSent = 0;
while (nBytesSent < gcf.clientStruct[idx].nDataOut){
int nSent = send(sock,(char*)(&gcf.clientStruct[idx].outbufferData[0]+nBytesSent),gcf.clientStruct[idx].nDataOut - nBytesSent,0 );
if (nSent == SOCKET_ERROR) {
// error sending
int err = WSAGetLastError();
if (err != WSAEWOULDBLOCK){// it's a "real" error
//sprintf_s(buf,255,"Client thread %d network error : %d",idx,err);
gcf.log(buf);
if (err == WSAECONNRESET){// connection forcibly closed
TCHAR buf[255];
nBytesSent = 0;
gcf.clientStruct[idx].bSend = false;
gcf.clientStruct[idx].clientThreadID = 0;
gcf.clientStruct[idx].index = -1;
gcf.clientStruct[idx].bClientRunning = false;
gcf.nClientsNb--;
closesocket(gcf.clientStruct[idx].sd);
swprintf_s(buf,255,_T("Client connection %d terminated (sending)"),idx);
gcf.log(buf);
}
gcf.log(_T("Unknown sending error"));
}// end "real" errors
}//end socket error
else{
nBytesSent += nSent; // add sent bytes to total
}
}// end send data
}// end while not finished sending
gcf.clientStruct[idx].bSend = false;// data was sent, reset flag
// LeaveCriticalSection(&critOUT);
}// end while ThreadRun
// Thread is exiting (Killed)
gcf.clientStruct[idx].bClientStopped = true;
} |
Partager