1 回答

TA贡献2036条经验 获得超8个赞
我认为你的问题非常标准:不注意TCP不实现消息边界的事实,只是通过连接传输两个不透明的字节流。
这意味着,当您将一串字节“Hello world从客户端”发送到连接的套接字(已建立的TCP连接)时,连接的另一端不知道客户端的消息在哪里结束,除非客户端以某种方式传达它本身;根本没有办法使用TCP本身来划分单个消息。
输入“应用程序级协议”:除非您打算使用TCP的数据交换任务自然地传输单个“消息” - 想象一下服务器将单个文件的内容转储到每个连接的客户端并关闭连接 - 您必须发明一些方法让客户端告诉服务器它发送的每条消息实际上在哪里结束。
考虑一下您的示例:在读取过程中,您基本上有一个循环,该循环从套接字重复读取数据块,具有单个退出条件:到达该套接字上的文件末尾。只有当远程端(在本例中为客户端)关闭其连接端时,才会报告 EOF,而客户端从不这样做:它发送一个字符串,然后等待服务器发回一些东西,但服务器从不回复,因为它永远不会完成读取。
有多种方法可以解决问题。
发明一个自定义协议(例如,在TLV系列中),它将实现消息成帧。
例如,在最简单的形式中,该协议可以定义为单个无符号字节,其中包含以下消息的长度(以字节为单位)。
然后,服务器将有一个两步过程来读取客户端的每条消息:读取单个字节;
如果成功,请读取由前导字节值定义的任意数量的后续字节;
成功后,请返回步骤 1 以阅读以下消息。
想出一个消息分隔符,如ASCII LF字符 - 可以编码为Go的字符串文本,并使服务器继续读取,直到遇到LF;一旦它发现了一个LF,它就知道它应该处理消息,然后开始读取另一个消息。
\n
围棋有方便的类型
布菲奥。读取器
在其标准包中,可以从由LF分隔的任何单个行中读取。io.Reader
具有更复杂的消息框架,例如使用 JSON 流发送 JSON 文档。
由库存包实现的解码器的一个经常监督的功能是,它可以解码JSON对象的流,以此为例。
encoding/json
可能性实际上很多,所以我只是触及了表面,我认为你应该明白这个想法。
- 1 回答
- 0 关注
- 93 浏览
添加回答
举报