gpt4 book ai didi

c++ - 使用 Winsock DLL 在简单的 TCP 回显服务器中分隔消息

转载 作者:可可西里 更新时间:2023-11-01 02:39:30 26 4
gpt4 key购买 nike

请考虑使用 TCP 和 Winsock DLL 的简单回显服务器。客户端应用程序从多个线程发送消息。服务器上的 recv 调用有时会返回存储在传递缓冲区中的多条消息。此时,服务器没有机会知道这是一条大消息还是多条小消息。

我读到可以将 setsockoptTCP_NODELAY 选项结合使用。除了 MSDN 声明之外,此选项的实现只是为了向后兼容,它甚至不会改变上述行为。

当然,我可以在每条消息的末尾引入某种分隔符,并在服务器端拆分消息。但我认为不应该这样做。那么,正确的做法是什么?

最佳答案

首先,TCP_NODELAY 不是执行此操作的正确方法...TCP 是一种字节流协议(protocol),任何给定的连接仅维护字节顺序 - 不一定是任何给定的 send/。依赖不使用任何同步的多个线程甚至能够将它们想要一起发送的消息保存在流中,这在本质上是错误的。例如,假设线程 1 想要发送两个字节的消息“AB”,线程 2 想要发送“XY”...假设线程 1 首先启动并且输出缓冲区只有一个字节的空间,send 将“A”排入队列并让线程 1 知道它只发送了一个字节(因此它应该循环并重试 - 最好在等待输出队列有更多空间的通知之后)。然后,线程 2 可能会在线程 1 获取“Y”之前将部分或全部“XY”放入队列。对于速度较慢且负载较大的机器(例如,当您的应用程序运行在 3G 网络上时,可能是一部正在播放视频和多任务的低功率手机),这类问题在连接速度较慢时会变得更加严重。

确保逻辑消息通过 TCP 保持在一起的方法包括:

  • 有一个从共享队列中按顺序拾取消息的发送线程(可以使用互斥锁让线程对消息进行排队)

  • 争夺一个锁(互斥锁),这样线程的 send 就可以不间断地循环到 send 直到发送完一条完整的消息(这不会不适合某些应用程序,因为任何线程在进行通信工作时都可能会暂停很长时间)

  • 每个线程使用单独的 TCP 连接

关于c++ - 使用 Winsock DLL 在简单的 TCP 回显服务器中分隔消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24799509/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com