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:
- Maybe there is some Perl module that deals with it?
- Maybe I can just turn off fragmentation, but wouldn’t it cause more transmission fails?
- I can just add the message length to the sent message, and I will call
recvuntil I receive the whole message, but isn’t it just ugly? - Anything else?
What would the best solution be?
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()