Reputation: 27240
I have a socket comminucation between Perl client and C++ server.
Perl code:
if (!socket(SERVER, AF_INET, SOCK_STREAM, getprotobyname('tcp'))) {
die "Can't allocate socket\n";
} elsif (!connect(SERVER,sockaddr_in($PORT, $tcp_addr))) {
die "Can't connect to server at $tcp_addr port $PORT...\n";
}
SERVER -> autoflush(1);
print SERVER "$line";
If $line
was too long, it is being fragmented, and on the C++ server side I have to call recv
several times (without even knowing the actual expected length!).
What are the best ways to deal with it?
I thought of some ways:
recv
until I receive the whole message, but isn't it just ugly?What would the best solution be?
Upvotes: 3
Views: 879
Reputation: 182753
The best solution is to keep calling 'recv' until you have the whole message. If necessary to determine when you have the whole message, either prefix the message with its length or put a terminator after it. I'm not sure why you think that's ugly.
Upvotes: 5
Reputation: 16046
Add the message length as a 4byte header to the message. This is not ugly, but just as the "pros" do it. TCP/IP is a stream oriented protocol. You were just lucky that you got your messages in one recv call. It is possible to get any number of bytes, only half a message, one and a half message etc. as tcp/ip is transferring a continuous stream of bytes without any notion of packets at that level.
The good side of this is that you can buffer your messages in userspace and can read as many bytes as you want into that buffer, and the process multiple messages out of this buffer isntead of repeatedly calling recv()
Upvotes: 6