Linux 缓冲所有在套接字上接收到的消息。但在收到之前,这条消息有一个开始和一个结束。Linux 将这些消息顺序写入缓冲区,因此丢失了消息末尾的信息。
我知道在 Linux 中我可以使用 cmsg_header。但 Windows 不提供 send-/recvmsg() 程序。如何确定缓冲区平台无关的消息结束?
Linux 缓冲所有在套接字上接收到的消息。但在收到之前,这条消息有一个开始和一个结束。Linux 将这些消息顺序写入缓冲区,因此丢失了消息末尾的信息。
我知道在 Linux 中我可以使用 cmsg_header。但 Windows 不提供 send-/recvmsg() 程序。如何确定缓冲区平台无关的消息结束?
我不确定 TCP/IP 连接是否正在交换分隔良好的消息。路由器可以对数据包进行分段。(所以cmsg_header
可能不可靠)。
我所知道的所有基于 TCP/IP 的协议(HTTP、SMTP、X11、RPCXDR)都在应用程序级别处理消息组织。您的应用程序库需要以某种方式知道“消息”何时以及何时开始或结束。
只需按网络顺序在前 4 个字节中发送消息的长度。那么你就不会有这个问题了。
我认为 Winsock 等价于sendmsg
,recvmsg
是WSASendMsg
和WSARecvMsg
。LPWSAMSG
根据文档,他们采用的参数是基于 Posix.1g 规范的 msghdr 结构的结构。
面向网络的应用程序通常具有清晰的传输/业务逻辑分离。
业务层只操作整个消息。传输将整个消息传递到上游业务层,可能会从片段中组装连续的流,重新切片并将其重新解释为一系列消息。
传输层通常使用 [size(length=S)][payload(variable length)] 形式的协议消息与远程传输层通信。其中 [size] 是单个数字,其编组长度 S 为所有通信方所知。
传输层做的第一件事是等待从下游(异步或同步,无关紧要)接收 S 字节到临时缓冲区。完成后,它会解组接收到的数据并知道要接收的有效载荷 L 的长度。
一旦已知有效载荷 L 的长度,传输将等待从下游接收 L 个字节到临时缓冲区(可能必须组合多次读取),一旦完成,它就会通知应用层将整个组装消息传递到单个缓冲区中。
Linux 将这些消息顺序写入缓冲区,因此丢失了消息末尾的信息。
这是不正确的。接收端永远不会丢失任何“[关于]消息结尾的信息”。TCP 是一种字节流协议。您send()
的 s 或write()
s在 sender 处连接到其套接字发送缓冲区,然后从那里以 TCP 段和 IP 数据包的形式传输数据,但是传输决定这样做。
如果你想通过 TCP 发送消息,你必须完全自己实现它们。常用技术: