Hello,
I have C/C++ Winsock server, and C# client. In C# I'm using blocking socket
communication. Client sends some data (about 64kB) and receives answer (about
10B). The problem is, that after first connection, nearly all following are
false - server receives less data that client sends, next time more (seems like
server gets data from actual connection and that which haven't been received
before)... What can be done, to make both sides work correctly On server side
I'm receiving data as long, as recv function returns values greater than 0, but
it doesn't prevent me from receiving wrong amount of bytes... What seems strange is that when I restart
client (close it and start once more) it will always communicate correctly. But
if I try to communicate again without closing it, client will fail or work properly
(but chances of working correctly are very small). Any idea what can be done
[EDIT: I'm using TCP connection]
Best regards,
tytus

C/C++ Server and C# client - communication problem
rkarem
Hello Tytus,
when you say "after first connection", do you really mean that the client is disconnecting after it receives the answer
Assuming it is not, and also assuming the server isn't blocking (you mention the client is blocking, so I would presume the server is not... rather far-fetched, but bear with me), a possible explanation is that you are "receiving data as long as recv returns values greater than zero". If the server isn't blocking, and there aren't data in the buffer, recv will return SOCKET_ERROR (-1) and WSAGetLastError returns WSAEWOULDBLOCK. Now, if your server is reading data faster than they are buffered by the client, you would get this "hole" that your server might detect as an end of block. You might have a slight advantage on the first exchange of data, due to the time it takes to set up the communication on the server side, and this would explain why you always get it right on the first go.
The best way to fix this would be to set up some framing so that the server can detect when the block is finished without having to look at how the communication progresses. The easiest solution would be to prefix the block with a record stating the number of bytes in the block. At this point the server could just "count down" until it reaches the end. An alternative, if you are using a text transmission, would be to provide a START/STOP indication, which has the definite advantage of making resynchronization possible (and easier!).
If you cannot change the protocol, you might try to insert a delay. This means that when your server first detects a WSAEWOULDBLOCK, it should wait for a prefixed amout of time (a few msec will do), and then try again. If it hits another WSAEWOULDBLOCK, it might consider the packet ended as no more data are being buffered. The longer you wait, the safer is your bet that the packet is ended... yet you can never be absolutely sure (unless you are willing to wait for a very long time, which would be impractical in most cases): transmission errors, lost packets, the client being sluggish for some reason, any of these might cause a delay long enough to trigger a false positive.
HTH
--m