由于我创建了一个 TCP 套接字,因此在发送少量数据时很好。没有片段。所有数据都放在一个包中。但是当数据变得越来越大时。TCP包已经被分割成碎片了。。真的很烦人。是否有任何选项可以设置在套接字上,并且套接字会自动为我将碎片放入一个包中?
7 回答
It's a byte stream. All the bytes will arrive correctly and in the right order, but not necessarily when you want them. If you need to send anything more complex than one byte, you need another protocol on top of TCP. That's why there are all those other TCP/IP protocols like HTTP, SMTP etc.
不,那里没有。甚至在某些情况下您可能会收到 1 个字节。
TCP 为您提供可靠的双向字节流。它负责排序、传输层打包、重传和流控制。数十年的研究致力于优化其性能。很漂亮。您为所有这些便利付出的小代价是您必须在循环中写入和读取流,在接收时观察您可以处理的完整应用程序协议消息,并在发送时刷新未缓冲的字节。
欢迎来到套接字编程!
我会在这里插话并说,如果不对为您处理应用程序协议的库添加额外的依赖项,您几乎无法解决您的问题。有一些较低级别的消息打包库(谷歌的协议缓冲区等)可能会有所帮助。
习惯在循环中读取和写入 TCP 数据可能是最有益的。它经过验证并且非常便携..即使您在自己实际编写流编解码器时付出了很小的代价。
试几次。这是一种有用的体验,你可以重复使用,一旦你掌握了它,它真的不会那么困难和烦人(就像其他任何东西一样,真的)。
此外,单元测试相当容易(而不是处理深奥的库和带有不良/稀疏文档选项的不常见协议)..
考虑使用更高级别的消息传递库,如ZMQ。它为您处理所有消息打包和拆包。
You can optimize sockets reads to return larger chunks, on platforms that support it, by setting low watermark using setsockopt()
and SO_RECVLOWAT
. But you will still have to handle the possibility of getting bytes less than the watermark.
I think you want SOCK_SEQPACKET
(or possibly SOCK_RDM
). See socket(2).