0

我正在使用 linux 下的 Berkely SOCKET API 编写 TCP 服务器。现在客户端有一组规范,客户端发送的每个消息都基于这些规范,即从客户端发送的消息对应于规范指定的许多结构中的一个。现在的情况是服务器不知道客户端将在什么时间发送哪条消息。一旦我们得到消息,我们就可以弄清楚它是什么,但在此之前就不行了。客户端发送的消息长度可变,因此我们无法提前知道我们将收到什么消息。为了解决这个问题,我使用了以下方法:

const char *buf[4096] = { 0 };
          if ( recv (connected, buf, 4096, 0) == -1)
             {
               printf ("Error in recvng message\n");
               exit (-1);
             }

那就是我使用大小为 4096 的默认缓冲区(来自客户端的任何消息都不能大于此大小)。在该缓冲区中接收,然后我检查消息类型并采取相应的操作,如下所示:

struct ofp_header *oph;
oph=(struct ofp_header *)buf;
switch (oph->type)
{
case example_pkt:
handle_example_pkt();
break;
}

这很好用,但我只是想确认这是一种合适的方法,还是有比这更好的方法。非常感谢所有帮助。

谢谢。

4

1 回答 1

5

TCP 是基于流的。这意味着如果您使用的缓冲区大于您的消息,您也可能会收到下一条消息的一部分。

这意味着您将需要知道消息的大小并将任何其他数据合并到下一条消息中。有两种明显的方法可以做到这一点:

  1. 修改协议以将每条消息的大小作为消息的前几个字节发送。先读取大小,然后只读取那么多字节。

  2. 由于您知道每条消息的大小,因此请跟踪您读取的字节数。处理缓冲区中的第一条消息,然后从缓冲区中的剩余字节中减去该消息的大小。继续重复此过程,直到 A. 没有足够的字节剩余来识别消息类型或 B. 没有足够的字节用于检测到的类型的消息。保存所有剩余字节并再次调用 recv 以读取更多数据。

于 2012-01-31T14:29:49.360 回答