Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sockets 如何告诉TCP服务器特定消息已结束?_Sockets_Networking_Tcp_Network Programming_Network Protocols - Fatal编程技术网

Sockets 如何告诉TCP服务器特定消息已结束?

Sockets 如何告诉TCP服务器特定消息已结束?,sockets,networking,tcp,network-programming,network-protocols,Sockets,Networking,Tcp,Network Programming,Network Protocols,TCP客户端逐字节发送数据。那么,如何告诉服务器此消息已结束,新消息现在开始 一种方法是修复将作为书签发送的特殊字符,但该字符也可能是导致混淆的消息的一部分 任何其他最佳方法?一种可能的方法是,在发送实际消息之前,您可以发送特定消息中的字节数。当接收端接收到该数量的字节时,它可以开始接收下一条消息如果希望将字符用作消息结尾标记或消息的一部分,则需要使用转义序列 例如:使用字符“$”结束消息,使用“%”转义 i、 e 然后使用“$”结束消息 或者全部发送消息开始时要接收的字节数(如果您不知道该点完

TCP客户端逐字节发送数据。那么,如何告诉服务器此消息已结束,新消息现在开始

一种方法是修复将作为书签发送的特殊字符,但该字符也可能是导致混淆的消息的一部分


任何其他最佳方法?

一种可能的方法是,在发送实际消息之前,您可以发送特定消息中的字节数。当接收端接收到该数量的字节时,它可以开始接收下一条消息

如果希望将字符用作消息结尾标记或消息的一部分,则需要使用转义序列

例如:使用字符“$”结束消息,使用“%”转义

i、 e

然后使用“$”结束消息


或者全部发送消息开始时要接收的字节数(如果您不知道该点完整消息的长度,则发送消息块)。

如果消息是二进制的,则不可能使用特殊字符进行分隔编码。标签长度值(TLV)编码最适合于此

比如说

 +--------+----------+----------------+    
 |  Tag   | Length   |  Content       |    
 | 0x0001 |  0x000C  | "HELLO, WORLD" |    
 +--------+----------+----------------+

除此之外,您还可以有多个消息类型

检查在开源通信框架中使用的实现。特别是第892行的IncomingPacketHandleHandOff()

它保证接收到的第一个字节指定数据包头的大小(小于255字节)。一旦接收到足够的字节以重建报头,就可以检查报头以确定要接收的剩余大小(数据部分)。如果传入的字节比预期的头和数据部分多,请查看第一个字节并重新开始


使用书签字符是在网络堆栈的基本级别上使用的,但必须小心执行,以避免进一步的复杂化。

字节数也可以是消息中的一个数字,服务器如何知道消息已结束或开始?我一直在做的是在消息中添加一个伪头。任何消息的前四个字节都会告诉我们,它后面有多少字节对应于消息TCPHeader->PseudoHeader1->Message1->PsuedoHeader2->Message2IMHO从消费者的角度来看,这是实现这一点的最佳方法,无论是您协议的服务器还是客户端。对于带有长度前缀的消息,您知道要读取多少数据,sizeof(长度前缀),一旦获得长度,您就知道消息的确切大小。这使得解析消息非常有效。另一种选择是消息终止符字符,它要求使用者扫描整个消息以查找终止符。我在这里谈论长度前缀消息:(很抱歉缩短了链接,实际链接对于注释来说太长了)Raza和@LenHolgate我的观点是,在第二条消息中,TCP如何知道X是伪头,而不是消息体?您必须以能够区分两者的方式实现状态机。对于每个接收到的消息,首先读取伪头,然后读取消息正文。您还必须注意一些错误情况。在第二条消息中,TCP如何知道%是转义字符而不是消息正文?字节数也一样。如何告诉TCP服务器(在第二条消息中)新消息的标记值不是旧消息的一部分。这应该由程序的状态来处理。您可以将序列号作为一个附加参数来显式标记这是第一个,也就是第二个。但这对于基于TCP的应用程序来说并不是必需的。如果您正在设计应用程序级协议,我建议您阅读Robin Sharp的协议设计原则:)。您可能没有抓住要点。示例消息:
2222222
这里,前两个2是第一条消息的一部分,第二个2是序列号,其余2是第二条消息的一部分。服务器应该如何根据您的回答确定哪个2是序列numebr?这必须以您的帧格式定义,读取字节数必须计数,状态应该保持,例如。我现在明白您的意思了。谢谢服务器需要完成大量工作。:)
 +--------+----------+----------------+    
 |  Tag   | Length   |  Content       |    
 | 0x0001 |  0x000C  | "HELLO, WORLD" |    
 +--------+----------+----------------+