sockets - how to check if there is data in buffer?

Red Squirrel

No Lifer
May 24, 2003
69,091
12,938
126
www.anyf.ca
Is there a way in sockets to check if there is data in the buffer without using recv()? I'm writing this program that works with a protocol and I just ran into a packet that gets compressed. So there is no way of knowing how big the packet is until it is decompressed. I cannot decompress it if I don't know its size, since if I call recv with too big of a value, then it just blocks forever until more data is sent. So is there a way to check against the buffer? My socket class takes data one byte a time, so I could have it call up that function then return as soon as buffer is empty.

For now I just want to ingnore the compressed packets till I figure out how to code the algorithm to decompress them (it's gzip I think). With this particular application I can get away with ignoring packets, as long as I still take them properly, so the next packet can be handled properly.
 

dighn

Lifer
Aug 12, 2001
22,820
4
81
You can look at ioctlsocket() and the FIONREAD parameter. If this is not windows then the function name may be different, but it should work the same way.

However from what you describe, what you are doing doesn't seem like it's going to work reliably. You appear to be using TCP (being able to read one byte at a time) which does not have the notion of a "packet". If you don't have some kind of packet mechanism built into your application protocol, you can't really work with packets. Say you send some bytes in a single call on the sender, on the receiver you might need several read calls to get the whole thing even given sufficient buffer. If you code it in such a way that it separates packets by checking for empty buffers, you will get partial packets because the buffer will very likely often be empty inbetween calls in real world situations. You really need a size field in the application protocol so you can reliably read entire packets despite the nature of streaming sockets, in which case you wouldn't need this anyway.

Another solution is to use non-blocking sockets, and detect for the end of packet somehow (perhaps an end marker for zip?). You can select() for incoming data, and use a non-blocking recv() to read some amount, examine it to see if you've got the end of the packet, if not continue. I don't think blocking recv() always blocks forever anyway but non-blocking should behave more reliably as you expect it to.
 

Red Squirrel

No Lifer
May 24, 2003
69,091
12,938
126
www.anyf.ca
Yeah its not my protocol. The protocol itself has various machanisms to detect the end, such as a packet size parameter (so read first nn bytes first to get size) or fixed size. Each packet has a number, so the packet handler gets 1 byte, then acts depending on what the number is. (Ex: packet 0x1 might be 3 bytes, so only read 2 more bytes, then expect next byte to be another packet, and so on)

Problem is, because some are gzipped, I need to decompress them before knowing how big they are, which to me seems impossible, but guess there must be a way. Since like you said, if I get a gzipped packet followed by another packet right away, then theres no way of really knowing as its just a stream once it hits the client.
 

dighn

Lifer
Aug 12, 2001
22,820
4
81
Maybe you'll just have to delve down into the gzip format to be able to find the size/end, or find a gzip implementation that can do this...
 

Nothinman

Elite Member
Sep 14, 2001
30,672
0
0
You'll pretty much have to use non-blocking sockets and use select, poll or epoll to determine when there's data ready to be received.