判断socket上是否还有数据并丢弃
我正在 Linux 下编写一个接口,它从 TCP 套接字获取数据。用户提供一个Buffer来存储接收到的Data。如果提供的缓冲区太小,我只想返回一个错误。 第一个问题是确定缓冲区是否太小。 recv() 函数只返回实际写入缓冲区的字节数。如果我使用 recv() 联机帮助页上规定的 MSG_TRUNC 标志,它仍然返回相同的结果。 第二个问题是丢弃仍在套接字中排队的数据。因此,如果我确定我提供的缓冲区太小,我只想擦除套接字上留下的所有内容。除了再次关闭并打开套接字或只是接收直到什么都没有之外,还有其他方法可以做到这一点吗? 最好的问候
托比
I'm writing an Interface under Linux which gets Data from a TCP socket. The user provides a Buffer in which the received Data is stored. If the provided Buffer is to small I just want to return an Error.
First problem is to determine if the Buffer was to small. The recv() function just returns me the amount of bytes actually written into the Buffer. If I use the MSG_TRUNC flag stated on the recv() manpage it still returns me the same.
Second problem is to discard the data still queued in the socket. So if I would determine that my provided Buffer was to small I just want to erase everything which is left on the socket. Is there any other ways to do so except Closing and opening the socket again or just receive until nothing is left?
Best Regards
Toby
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如手册页中所述,MSG_TRUNC 仅对数据包套接字(例如 UDP)有效,因此对于基于流的 TCP 套接字,这将无法按照您的要求工作。 stackoverflow 和其他地方实际上有数百篇帖子讨论在 TCP 上保留应用程序消息边界(提示:您需要自己执行此操作,TCP 是字节流接口,但不是),因此我不会在这里详细介绍,我只想说,您需要一种机制来知道应用程序“消息”或“数据包”在recv()端有多大,以便您能够通过TCP执行您想要的操作(或者您需要切换到UDP) 。
对于 TCP,如果您需要“排空”套接字,则读取直到没有剩余数据为止是可行的,但是,您再次需要考虑如上所述的消息边界,这样您就不会读完一条“消息”并开始吃东西进入下一个(同样,要记住的最重要的一点是 TCP 提供了字节流接口,并且不一定保留您的应用程序级数据包或消息的概念)。
As documented in the man page, MSG_TRUNC is only valid for packet sockets (e.g. UDP) so this will not work as you want for your TCP socket which is stream based. There are literally hundreds of posts on stackoverflow and elsewhere that talk about preserving application message boundaries on TCP (hint: you need to do this yourself, TCP is a byte stream interface and doesn't) so I won't go into the details here, suffice it to say, you need a mechanism to know how big an application "message" or "packet" is on the recv() side to enable you to do what you want over TCP (or you need to switch over to UDP).
For TCP, if you need to "drain" the socket, reading until there is no data left would work, however, again, you need to consider message boundaries as mentioned above so that you do not read through one "message" and start eating into the next (again, most important point to remember is that TCP provides a byte stream interface and will not necessarily preserve your concept of application level packets or messages).