Skip to main content
GameDev.net gamedev.net
🔒 Locked

sent empty packets?

Started by alexscorpion Aug 22, 2006 at 10:29 AM 9 replies 1.9k views
Original Post
alexscorpion
alexscorpion
i have client program that automatically exchanges files with server. the problem is that the client somehow sends packets with ZERO length. in the code that is supposed. it happens both in loopback(127.0.0.1) and in remote connection mode. have that happened to you and have you got any suggestions? what i do is just send()ing some strings and file parts to the dest. all they are not '0' long. the problem appears after the transfer. some how the last packet is recv()ed twice...
What man is a man, that makes world no better?
markr
markr
Packets with 0 bytes of data are typically valid. This is certainly true in UDP and some other protocols.

Some protocols use a zero-byte datagram as a kind of "hello".

Of course TCP is a stream based system so boundaries are not preserved; sending 0 bytes is not a meaningful operation, and recv() will ONLY return 0 when the connection has been closed.

Mark
hplus0603
hplus0603
Are you using TCP or UDP? In TCP, a return value of 0 from a recv() call means that the other end disconnected cleanly. There are no 0-length transmittals in TCP, because TCP is a stream protocol.

In UDP, it's legal to use 0-size packets, because UDP is a message protocol.
enum Bool { True, False, FileNotFound };
alexscorpion
alexscorpion
it is TCP and that is the weird thing. i dont get 0 on recv() but after terminition of the string the displayed is like this ""
case FD_READ: // Receive data          {           char buff[4097];           int nRet = recv(mainsock, buff, 4096, 0);             if(nRet == 0 || nRet == SOCKET_ERROR) // connection closed              {               MessageBox(NULL, "Connection reset by remote side.",                                           "Error", MB_OK | MB_ICONERROR);               break;              }                           buff[nRet]='\0'; // terminate accepted string             ShowReceived(buff);          }break;


actually i used tcpdump to get detailed info of the packets transfer and there was many 0 long packets.
What man is a man, that makes world no better?
markr
markr
You will see lots of packets with no data in them; these will generally be acknowledgements or other metadata. This is totally normal.

Your code above is assuming that each chunk of data is a printable string; this won't generally be the case, the client may send zeroes which are valid. You may think these are empty "" but in fact they do contain data- you just can't see them. The same is true of other nonprintable characters.

You should find that recv() returns 0 *ONLY* when the connection is closed and at no other time. This is its normal behaviour for stream sockets.

Mark
alexscorpion
alexscorpion
why does recv() intersept that metadata? it is not supposed to...
What man is a man, that makes world no better?
Anon Mike
Anon Mike
Quote:
Original post by alexscorpion
i dont get 0 on recv() but after terminition of the string the displayed is like this ""

You are likely recv'ing a 0 or some other undisplayable character. You should use a debugger to look at the raw data.
-Mike
hplus0603
hplus0603
Quote:
Original post by alexscorpion
why does recv() intersept that metadata? it is not supposed to...


recv() (and send()) don't know about the "metadata" (which I would call "protocol framing"). TCP, itself, sends packets back and forth to negotiate window sizes, re-try after time-outs, acknowledge received data, etc. Some of those packets can contain zero data; that's perfectly fine. TCP is a stream protocol, not a packet protocol, so send()/recv() only see the stream.
enum Bool { True, False, FileNotFound };
alexscorpion
alexscorpion
we went a little off topic.
the question is: why my program sends empty packets when there is no such call to send()?
code snippet:
nRet = send(sckt, "request", 8, 0);nRet = recv(sckt, buff, 4096, 0);buff[nRet]='\0'; // terminate accepted stringif(!strcmp(buff, "acknowledged!")){// this is another method sprintf(buffer, "~file~%s~%lu~", fNameCopy[iFilesSent], dwFileSz); MessageBox(NULL, buffer, "sending", MB_OK); nRet = send(mainsock, buffer, sizeof buffer, 0);}

and when i test it with a server, the screen looks like this:
[screen]
1 client said:
2 request
3 client said:
4
5 client said:
6
7 client said:
8
9 client sends you file do you accept?
[/screen]
after line 2 and before line 3 the server sends the "acknowledged!". then i click on the MessageBox of the cilent and lines 3,4,...appears.
any suggestion?
p.s. the server is smart enough to not show parts of the file to the screen.
and the problem happens before any binary data has arrived...
it happens after that also because it's a loop after all.
What man is a man, that makes world no better?
Anon Mike
Anon Mike
Have you bothered to do this yet:
Quote:
You are likely recv'ing a 0 or some other undisplayable character. You should use a debugger to look at the raw data.

Looking at your data might you some insight into why you're receiving it in the first place. And printf is not really a valid way to to look at your data unless you're 100% sure it consists entirely of printable characters, which obviously it doesn't.

Your latest snippet also doesn't check for errors on recv. I can easily imagine that you've gone into an infinite loop of recving -1 characters and thus print garbage.
-Mike
hplus0603
hplus0603
Do what Mike says and use the debugger.
Further, use something like Ethereal (now known as WireShark) to see what your machine is actually sending.
Last, read the Forum FAQ part about TCP streams, and how calls to send() may be coalesced or split apart by the implementation.
enum Bool { True, False, FileNotFound };

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.