Tcp/Ip send() does sometimes not succeed
-
florianhaar wrote:
Frustrating
Indeed! Which select are you using? Can you post the code you use to receive (it's almost always a problem on the receiving end)? Mark
Thanks for your help so far Mark. I hope this code snippet gives you an idea for a solution: TIMEVAL tv; tv.tv_sec=0; tv.tv_usec=5; FD_ZERO(&clientSet); FD_SET(theClient->sock,&clientSet); if ((errCode=select(0,&clientSet,NULL,NULL,&tv))>0) { if ((recvMsgSize=recv(theClient->sock,addBuffer,maxRead,0))<=0) { //error handling ... } else message handling... I do not receive an error or a message. Select() returns only timeout. Flo
-
Thanks for your help so far Mark. I hope this code snippet gives you an idea for a solution: TIMEVAL tv; tv.tv_sec=0; tv.tv_usec=5; FD_ZERO(&clientSet); FD_SET(theClient->sock,&clientSet); if ((errCode=select(0,&clientSet,NULL,NULL,&tv))>0) { if ((recvMsgSize=recv(theClient->sock,addBuffer,maxRead,0))<=0) { //error handling ... } else message handling... I do not receive an error or a message. Select() returns only timeout. Flo
if ((recvMsgSize=recv(theClient->sock,addBuffer,maxRead,0))<=0) ... What is maxRead? How are you handling if recvMsgSize < maxRead after the call?
-
if ((recvMsgSize=recv(theClient->sock,addBuffer,maxRead,0))<=0) ... What is maxRead? How are you handling if recvMsgSize < maxRead after the call?
maxRead is the maximum number of bytes the buffer can store. if recvMsgSize is smaller than maxRead (which is normally the case) I copy the data to additional buffers and combine them as soon as all bytes are received. With my problem the data received is always smaller than maxRead.
-
Hi! I am currently programming server/client stuff with the c++ functions send and recv. Normally everything works fine but sometimes the client tells me it has sent a message successfully but it is not received by the server. I tracked the packets in the network and no packet had been sent. Documentation says not every successful call to send() guarantees that the data is received by the client. Unfortunately the packet is never sent (waited up to 3 minutes). Since Tcp/Ip is a reliable protocol, I expected the packets to be received by the client as long as the connection is not terminated. How can I make sure that send really sends my data? Is there a flush() command? (using Tcp/Ip non blocking windows socket, checking for send/receive with select). Any help would be greatly appreciated!!! Thx Flo P.S. Before you ask: it has to be c++ send and recv - no MFC or C# stuff...
If I remember it correctly, If the packet size become too small, very small that it doesnt send it until the successive packets join together to make good "chunk". It's somewhat termed as "Neigile's" Nagle algorithm or so. just check the size of the packets your are sending. -- modified at 13:16 Friday 26th January, 2007
Code-Frog:So if this is Pumpkinhead. Time for him to run and hide. It's an interesting thought really.
-
If I remember it correctly, If the packet size become too small, very small that it doesnt send it until the successive packets join together to make good "chunk". It's somewhat termed as "Neigile's" Nagle algorithm or so. just check the size of the packets your are sending. -- modified at 13:16 Friday 26th January, 2007
Code-Frog:So if this is Pumpkinhead. Time for him to run and hide. It's an interesting thought really.
Nagle :) The data is sent after (by default on Windows Sockets) 200ms though. Mark
-
Nagle :) The data is sent after (by default on Windows Sockets) 200ms though. Mark
-
maxRead is the maximum number of bytes the buffer can store. if recvMsgSize is smaller than maxRead (which is normally the case) I copy the data to additional buffers and combine them as soon as all bytes are received. With my problem the data received is always smaller than maxRead.
hmmm From what I've seen there shouldn't be a problem. You've debugged the code? Examining network packets isn't necessarily the way to debug since the potocol is free to re-packetize your data as needed. Have you changed any socket options on either end? There's a bug in the code somewhere :) Mark
-
hmmm From what I've seen there shouldn't be a problem. You've debugged the code? Examining network packets isn't necessarily the way to debug since the potocol is free to re-packetize your data as needed. Have you changed any socket options on either end? There's a bug in the code somewhere :) Mark
I guess I have to think through my code step by step once again. At least I know now, that send() should send after 200ms as long as the connection is established. Thanks again for your help! Flo
-
I guess I have to think through my code step by step once again. At least I know now, that send() should send after 200ms as long as the connection is established. Thanks again for your help! Flo
:) If you'd like to post the send-side code I'd be happy to look at it as well. Mark
-
:) If you'd like to post the send-side code I'd be happy to look at it as well. Mark
I generally agree with Mark's observation that problems like this are almost always caused by code on the receiving side. Here, you have set the timeout for select() to 5 microseconds. That's way too short. Your understanding of the send() function is slightly wrong. send() does not actually send bytes out over the wire; that happens later when the winsock TCP stack determines that it's time to send data on the wire, after considertion of things like Nagle, delayed ACK etc. Rather, a successful call to send() only indicates that the winsock stack has successfully transferred data in your user buffer to its internal winsock buffer. The return value from send() tells you exactly how much of your buffer has been accepted; you should therefore inspect the returned value to ensure that winsock transferred everything to its internal buffer. So, if you are debugging and single-stepping through your code, and you see a successful completion of the call to send(), then it's probably still too early for a sniffer to see the actual data on the wire. That will happen, but it will happen at some indeterminate time in the future. Mike
-
I generally agree with Mark's observation that problems like this are almost always caused by code on the receiving side. Here, you have set the timeout for select() to 5 microseconds. That's way too short. Your understanding of the send() function is slightly wrong. send() does not actually send bytes out over the wire; that happens later when the winsock TCP stack determines that it's time to send data on the wire, after considertion of things like Nagle, delayed ACK etc. Rather, a successful call to send() only indicates that the winsock stack has successfully transferred data in your user buffer to its internal winsock buffer. The return value from send() tells you exactly how much of your buffer has been accepted; you should therefore inspect the returned value to ensure that winsock transferred everything to its internal buffer. So, if you are debugging and single-stepping through your code, and you see a successful completion of the call to send(), then it's probably still too early for a sniffer to see the actual data on the wire. That will happen, but it will happen at some indeterminate time in the future. Mike
Thanks Mike! Maybe you meant to post this to the OP :) For some reason I assumed his code was in a loop. If it's not then that 5microsecond timeout is definitely not going to work (well, rarely). Mark
-
I guess I have to think through my code step by step once again. At least I know now, that send() should send after 200ms as long as the connection is established. Thanks again for your help! Flo
Hi Flo, Check out Mike O'Neill's reply above. I asked previously how you're handling it when you don't receive the number of bytes requested. Are you looping until you get the bytes you're expecting or just trying to recv once after the 5microsecond wait? Mark