I'm trying to write a very simple chatting program using completion port in Winsock. I'm imaging in my program, message will be sent from Client 1 -> through Server -> Client 2 and vice versa. Thus, I wrote a worker thread for Per-Handle Data as following:
Code:
DWORD WINAPI ServerWorkerThread(LPVOID CompletionPortID)
{
	HANDLE CompletionPort = (HANDLE) CompletionPortID;
	DWORD BytesTransferred;
	LPPER_HANDLE_DATA PerHandleData;
	LPPER_IO_OPERATION_DATA PerIoData;
	DWORD SendBytes, RecvBytes;
	DWORD Flags;
        SOCKET  sourceClientSocket; 

	while(TRUE)
	{
		if (GetQueuedCompletionStatus(CompletionPort, &BytesTransferred,
			(LPDWORD)&PerHandleData, (LPOVERLAPPED *) &PerIoData, INFINITE) == 0)
		{
			printf("GetQueuedCompletionStatus() failed with error %d\n", GetLastError());
			return 0;
		}
		else
			printf("GetQueuedCompletionStatus() is OK!\n");
		
                
		// First check to see if an error has occured on the socket and if so
		// then close the socket and cleanup the SOCKET_INFORMATION structure
		// associated with the socket
		if (BytesTransferred == 0){
			printf("Closing socket %d\n", PerHandleData->Socket);
			if (closesocket(PerHandleData->Socket) == SOCKET_ERROR)	{
				printf("closesocket() failed with error %d\n", WSAGetLastError());
				return 0;
			}
			else
				printf("closesocket() is fine!\n");
			
			GlobalFree(PerHandleData);
			GlobalFree(PerIoData);
			continue;
		}
		

		// Check to see if the BytesRECV field equals zero. If this is so, then
		// this means a WSARecv call just completed so update the BytesRECV field
		// with the BytesTransferred value from the completed WSARecv() call
		if (PerIoData->BytesRECV == 0){
			PerIoData->BytesRECV = BytesTransferred;
			PerIoData->BytesSEND = 0;
		}else	{
			PerIoData->BytesSEND += BytesTransferred;
		}
		
		if (PerIoData->BytesRECV > PerIoData->BytesSEND){
			// Post another WSASend() request.
			// Since WSASend() is not gauranteed to send all of the bytes requested,
			// continue posting WSASend() calls until all received bytes are sent.

                        // Keep the source client's socket
                        // and pass target client's socket
                        sourceClientSocket =  PerHandleData->Socket;
                        PerHandleData->Socket = targetClientSocket;

			ZeroMemory(&(PerIoData->Overlapped), sizeof(OVERLAPPED));
			PerIoData->DataBuf.buf = PerIoData->Buffer + PerIoData->BytesSEND;
			PerIoData->DataBuf.len = PerIoData->BytesRECV - PerIoData->BytesSEND;
			
                        //send to target client
			if (WSASend(PerHandleData->Socket, &(PerIoData->DataBuf), 1, &SendBytes, 0,
				&(PerIoData->Overlapped), NULL) == SOCKET_ERROR)	{
				if (WSAGetLastError() != ERROR_IO_PENDING){
					printf("WSASend() failed with error %d\n", WSAGetLastError());
					return 0;
				}
			}else
				printf("WSASend() is OK!\n");

		}else{

			PerIoData->BytesRECV = 0;
                        PerHandleData->Socket = sourceClientSocket; // Pass the source client socket so Server will be back to listen to the source client. 			

			// Now that there are no more bytes to send post another WSARecv() request
			Flags = 0;
			ZeroMemory(&(PerIoData->Overlapped), sizeof(OVERLAPPED));
			PerIoData->DataBuf.len = DATA_BUFSIZE;
			PerIoData->DataBuf.buf = PerIoData->Buffer;
			
			if (WSARecv(PerHandleData->Socket, &(PerIoData->DataBuf), 1, &RecvBytes, &flags,
				&(PerIoData->Overlapped), NULL) == SOCKET_ERROR)	{
				if (WSAGetLastError() != ERROR_IO_PENDING){
					printf("WSARecv() failed with error %d\n", WSAGetLastError());
					return 0;
				}
			}else
				printf("WSARecv() is OK!\n");
		}
	}
}
But it can only forward the first message. From the second one, it runs incorrectly.
Can someones please point me how to fix it or if there is any alternative way to do so using completion port? Thanks.