如何处理Perl TCP套接字中的消息碎片?

时间:2011-09-15 08:08:56

标签: c++ perl sockets tcp communication

我在Perl客户端和C ++服务器之间进行套接字通信。

Perl代码:

  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";

如果$line太长,它就会被分割,而在C ++服务器端,我必须多次调用recv(甚至不知道实际的预期长度!)。

处理它的最佳方法是什么?

我想到了一些方法:

  1. 也许有一些Perl模块可以处理它?<​​/ li>
  2. 也许我可以关闭碎片,但不会导致更多的传输失败吗?
  3. 我可以将消息长度添加到已发送的消息中,我会调用recv直到收到整条消息,但这不是很难看吗?
  4. 还有别的吗?
  5. 最佳解决方案是什么?

2 个答案:

答案 0 :(得分:5)

将消息长度添加为消息的4字节标头。这并不难看,但正如“专业人士”所做的那样。 TCP / IP是面向流的协议。你很幸运,你在一次电话会议中得到了你的消息。有可能获得任意数量的字节,只有一半的消息,一个半的消息等,因为tcp / ip正在传输连续的字节流,而没有任何数据包的概念。

这方面的好处是你可以在用户空间中缓冲你的消息,并且可以在你的缓冲区中读取任意数量的字节,并且从这个缓冲区中取出多个消息而不是重复调用recv()

答案 1 :(得分:4)

最好的解决方案是继续调用'recv'直到收到整条消息。如果需要确定何时拥有整个消息,请在消息前面加上其长度,或在其后添加终结符。我不确定你为什么觉得这很难看。