套接字协议基础知识

发布于 2024-08-23 13:18:35 字数 537 浏览 2 评论 0原文

最近,在阅读 Socket 编程 HOWTO 时,我突然想到以下部分:

但是,如果您打算重复使用套接字进行进一步的传输,则需要意识到套接字上没有“EOT”(传输结束)。我重复一遍:如果套接字发送或接收在处理 0 字节后返回,则连接已断开。如果连接没有断开,您可能会永远等待recv,因为套接字不会告诉您没有更多内容可读取(目前)。现在,如果您稍微思考一下,您就会意识到套接字的一个基本事实:消息必须是固定长度(恶心),或者是分隔(耸耸肩) ),或指出它们有多长(更好),或通过关闭连接结束。选择完全取决于您(但有些方式比其他方式更正确)。

本节重点介绍如何编写套接字“协议”来传递消息的 4 种可能性。我的问题是,实际应用程序的首选方法是什么?

正如本文或多或少断言的那样,通常最好在每条消息中包含消息大小(大概在标头中)吗?是否存在其他方法更可取的情况?

Recently, while reading a Socket Programming HOWTO the following section jumped out at me:

But if you plan to reuse your socket for further transfers, you need to realize that there is no "EOT" (End of Transfer) on a socket. I repeat: if a socket send or recv returns after handling 0 bytes, the connection has been broken. If the connection has not been broken, you may wait on a recv forever, because the socket will not tell you that there's nothing more to read (for now). Now if you think about that a bit, you'll come to realize a fundamental truth of sockets: messages must either be fixed length (yuck), or be delimited (shrug), or indicate how long they are (much better), or end by shutting down the connection. The choice is entirely yours, (but some ways are righter than others).

This section highlights 4 possibilities for how a socket "protocol" may be written to pass messages. My question is, what is the preferred method to use for real applications?

Is it generally best to include message size with each message (presumably in a header), as the article more or less asserts? Are there any situations where another method would be preferable?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

苏别ゝ 2024-08-30 13:18:35

常见协议要么在标头中指定长度,要么进行分隔(例如 HTTP)。

请记住,这还取决于您使用 TCP 还是 UDP 套接字。由于 TCP 套接字是可靠的,因此您可以确保获得塞入其中的所有内容。对于 UDP,情况有所不同并且更加复杂。

The common protocols either specify length in the header, or are delimited (like HTTP, for instance).

Keep in mind that this also depends on whether you use TCP or UDP sockets. Since TCP sockets are reliable you can be sure that you get everything you shoved into them. With UDP the story is different and more complex.

北恋 2024-08-30 13:18:35

这些确实是我们对 TCP 的选择。例如,HTTP 混合使用第二个、第三个和第四个选项(双换行符结束请求/响应标头,其中可能包含 Content-Length 标头或指示分块编码,或者可能会显示Connection:close并且不给你内容长度,但希望你依赖于读取EOF。)

我更喜欢第三个选项,即self - 描述消息,尽管在合适的情况下固定长度很容易。

These are indeed our choices with TCP. HTTP, for example, uses a mix of second, third, and forth option (double new-line ends request/response headers, which might contain the Content-Length header or indicate chunked encoding, or it might say Connection: close and not give you the content length but expect you to rely on reading EOF.)

I prefer the third option, i.e. self-describing messages, though fixed-length is plain easy when suitable.

揪着可爱 2024-08-30 13:18:35

如果您正在设计自己的协议,那么首先看看其他人的工作;可能已经存在类似的东西,您可以“按原样”使用或重新调整用途和调整。例如; ISO-8583 用于金融交易,HTTPPOP3所有人都以不同的方式做事,但都以被证明有效的方式...事实上,无论如何,这些事情都值得一看,因为您将学到很多关于现实世界协议如何组合在一起的知识。

如果您需要编写自己的协议,那么恕我直言,尽可能首选长度前缀消息。对于接收方来说,解析它们既简单又高效,但如果在开始发送数据之前确定数据长度的成本很高,那么生成它们可能会更困难。

If you're designing your own protocol then look at other people's work first; there might already be something similar out there that you could either use 'as is' or repurpose and adjust. For example; ISO-8583 for financial txns, HTTP or POP3 all do things differently but in ways that are proven to work... In fact it's worth looking at these things anyway as you'll learn a lot about how real world protocols are put together.

If you need to write your own protocol then, IMHO, prefer length prefixed messages where possible. They're easy and efficient to parse for the receiver but possibly harder to generate if it is costly to determine the length of the data before you begin sending it.

万人眼中万个我 2024-08-30 13:18:35

该决定应取决于您要发送的数据(它是什么,如何收集)。如果数据是固定长度的,那么固定长度的数据包可能是最好的。如果数据可以轻松(无需转义)分割为分隔实体,那么分隔可能会很好。如果您在开始发送数据片时知道数据大小,那么 len 前缀可能会更好。如果发送的数据始终是单个字符,甚至单个位(例如“开”/“关”),那么任何与固定大小的单字符消息不同的内容都会太多。

还要考虑协议如何演变。只要 EOL 分隔字符串本身不包含 EOL 字符,就可以使用。固定长度可能很好,直到数据可以用一些可选部分等来扩展。

The decision should depend on the data you want to send (what it is, how is it gathered). If the data is fixed length, then fixed length packets will probably be the best. If data can be easily (no escaping needed) split into delimited entities then delimiting may be good. If you know the data size when you start sending the data piece, then len-prefixing may be even better. If the data sent is always single characters, or even single bits (e.g. "on"/"off") then anything different than fixed size one character messages will be too much.

Also think how the protocol may evolve. EOL-delimited strings are good as long as they do not contain EOL characters themselves. Fixed length may be good until the data may be extended with some optional parts, etc.

春夜浅 2024-08-30 13:18:35

我不知道是否有更好的选择。在我们的实际情况(客户端-服务器应用程序)中,我们使用将总消息长度作为第一批数据之一发送的选项。它很简单并且适用于我们的 TCP 和 UDP 实现。在这两种情况下读取数据时,它使逻辑相当“简单”。对于 TCP,代码量相当小(相比之下)。 UDP 版本稍微复杂一点(轻描淡写),但仍然依赖于初始数据包中传递的大小来了解所有数据何时发送。

I do not know if there is a preferred option. In our real-world situation (client-server application), we use the option of sending the total message length as one of the first pieces of data. It is simple and works for both our TCP and UDP implementations. It makes the logic reasonably "simple" when reading data in both situations. With TCP, the amount of code is fairly small (by comparison). The UDP version is a bit (understatement) more complex but still relies on the size that is passed in the initial packet to know when all data has been sent.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文