2012-01-31 75 views
0

我正在使用Berkely SOCKET API在linux下编写TCP服务器。现在,客户端有一组规范,客户端发送的每条消息都基于这些规范,即客户端发送的消息对应于规范指定的许多结构之一。现在情况是,服务器不知道客户端将在什么时间发送哪条消息。一旦我们得到消息,我们可以弄清楚它是什么,但不是在此之前。由客户端发送的消息具有可变长度,所以我们不能提前知道我们将得到什么消息。为了解决这个我已经使用下面的方法:如何正确使用recv()sys调用

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

这工作得很好,但我只是想确认是不是一个合适的方法还是有别的东西,可能是比这更好。所有帮助非常感谢。

谢谢。

回答

5

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

这意味着您需要知道消息的大小并将所有附加数据合并到下一条消息中。有两个明显的方式来做到这一点:

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

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

+0

是的,这是我所害怕的。你可以请发布解决方案吗? – Abdullah 2012-01-31 14:37:08

+0

请参阅编辑答案。 – 2012-01-31 15:00:39

+0

非常感谢,非常感谢,现在很清楚该怎么办:)干杯:) – Abdullah 2012-01-31 15:57:42