Igor
Igor

Reputation: 27240

How to deal with message fragmentation in Perl TCP socket?

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:

  1. Maybe there is some Perl module that deals with it?
  2. Maybe I can just turn off fragmentation, but wouldn't it cause more transmission fails?
  3. I can just add the message length to the sent message, and I will call recv until I receive the whole message, but isn't it just ugly?
  4. Anything else?

What would the best solution be?

Upvotes: 3

Views: 879

Answers (2)

David Schwartz
David Schwartz

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

PlasmaHH
PlasmaHH

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

Related Questions