How do I flush a C++ socket?
Hi-
I'm working with sockets in C++, but not using the iostream library to access the sockets. Both sender and receiver reside on Linux workstations, and I'm using g++ to compile things. I'm working off RedHat 9.0. When I send on my socket, it doesn't necessarily flush a message before I send the next one. This results in parts (or all) of more than one message being concatenated together. I can code around this by parsing and reassembling them myself on the receiving end, but it'd be really great if someone out there would tell me how to flush a socket once the write() operation is complete. Then I could count on each message being discrete, and the parsing would be simplified. Anyone have any ideas out there? pjz |
hi piz,
I guess you are using tcp socket,aren't you? you should take the tcp connection as a stream,so at one end you send some bytes,say 2 bytes,then at the another end of connection ,you just simply recv 2 bytes,there is no need to think about the single packet, btw,the is a socket option you can use :TCP_NODELAY ,but i think you should avoid to use it until you are going to program some 'telnet' 'rlogin' like programs. goog luck |
Thanks. I have variable length records to exchange over the socket.
The solution I'm working with now involves using recv(sockt,buf,sizeof,MSG_PEEK) to see what's in the socket first. I then look for the message terminator, add up the length of the message to that point, then use recv(sockt,buf,sizeof,0) to pop just the right number of characters out of the buffer. That's a pretty effective solution. I wish I new how to flush the buffer without needing something like fd << flush, but it just doesn't seem to be out there. Thanks again for the suggestion. This is a great place to post, the community here is very responsive pjz |
Unfortunately, with TCP based communication, you generally have to use your own tricks to preserve packet boundaries. There are a number of ways you can do this. One way is to have a field in your packet that specifies the length of the packet so that you know exactly how many bytes to read in for any given packet.
|
Yeah, I thought of that. It would work, but would still require a MSG_PEEK,
then a parse, to retrieve the message length, so that the correct number of characters could be removed from the socket. It would be a little cleaner to implement on the receiving end, because the field with the count would be in a known place and have a known length. One wouldn't have to iterate the message to accumulate the count. On the sending end, it would be just a matter of using strlen() or something like it to get the length for passage in the message. The code I'm developing is for an event driven simulator application, and isn't intended to be "production quality", but "model quality". I think if I was developing for distribution, including the message length in the sent message would be the way to go. |
You wouldn't necessarily need to peek. If your count value is stored in the first bytes, just read those bytes from the socket to get the length, then read the number of bytes necessary for the rest of the packet.
You might want to restrict this to a reasonable maximum, and also use some sort of timeout mechanism to make sure you don't get stuck in a loop where you are expecting 50000 bytes, but only ever get sent 4, though. If you want to get a feel for how other TCP protocols work with regards to packet boundaries, you might want to take a look at some RFCs for established protocols. |
All times are GMT -5. The time now is 01:55 PM. |