网络编程。确定消息的结束

时间:2012-11-11 16:26:05

标签: c++ c sockets network-programming cross-platform

Linux缓冲在套接字上收到的所有收到的消息。但在收到之前,这些消息有一个开始和结束。 Linux会在缓冲区中按顺序写入此消息,从而丢失消息结束的信息。

我知道在Linux中我可以使用cmsg_header.But Windows不提供send- / recvmsg()程序。如何确定缓冲区平台上的消息结束?

5 个答案:

答案 0 :(得分:5)

我不确定TCP / IP连接是否正在交换分隔良好的消息。路由器可以分组数据包。 (所以cmsg_header可能不可靠。)

我所知道的所有基于TCP / IP的协议(HTTP,SMTP,X11,RPCXDR)都在应用程序级别处理消息组织。您的应用程序库需要以某种方式了解“消息”何时何地开始或结束。

答案 1 :(得分:4)

只需按网络顺序发送前4个字节的消息长度即可。那你就不会有这个问题了。

答案 2 :(得分:2)

我认为sendmsgrecvmsg的Winsock等价物是WSASendMsgWSARecvMsg。它们采用LPWSAMSG参数,根据documentation,这是一个基于msghdr结构的Posix.1g规范的结构。

答案 3 :(得分:1)

面向网络的应用程序通常具有明确的传输/业务逻辑分离。

业务层仅运行整个邮件。 Transport正在向上游业务层提供整个消息,可能会从片段中组合连续的流,重新切片,并将其重新解释为一系列消息。

传输层通常使用形式[size(长度= S)] [有效载荷(可变长度)]的协议消息与远程传输层进行通信。其中[size]是一个数字,其编组长度S为所有通信方所知。

传输层所做的第一件事是它等待从下游接收S字节(异步或同步,无关紧要)到临时缓冲区。完成后,它会解组收到的数据,并了解要接收的有效负载的长度L.

一旦有效载荷L的长度已知传输正在等待从下游接收L字节到临时缓冲区(可能必须组合多个读取)并且一旦完成它通知应用层将整个汇编的消息传递给它缓冲液中。

答案 4 :(得分:1)

  

Linux会在缓冲区中按顺序写入此消息,从而丢失消息结束的信息。

这不正确。从来没有任何“关于消息结束的信息”在接收端丢失。 TCP是字节流协议。您的send()write()已在发件人处连接,并将其连接到其发送缓冲区,并从那里以TCP段传输数据然而,传输决定这样做。

如果您想通过TCP发送消息,则必须自己完全实现它们。常用技巧:

  • 在消息前发送一个长度字
  • 封装消息,例如在STX和ETX之间,如果它出现在消息中,则适当地转换为ETX(ESC ETX),因此在消息中出现时自动转换ESC(ESC ESC)
  • 使用自描述协议,例如XML。