==========TCP 编程的相关问题==========
資深大佬 : FreeWong 25
对方通过单片机使用 TCP 客户端的形式(短连接)与我写的服务端进行通讯
他们设计的协议是基于文本的,类似以下格式
@Start:A01:25.41,A02:36.1#
其中#号表示一条完整的可解析的数据的结尾,同时 TCP 客户端要求当服务器收到一条完整的数据后,要回复 @Received 用于表示接收到这条数据。
并且客户端会等待我的这个回复,才会断开 TCP 客户端一侧的连接,十几秒都没有收到则主动断开。(我们不考虑它主动断开的情况)
如果服务端没有回复,则到下一个通讯时间节点时,再次将前面没有收到回复的数据补发,然后再接着发送当前时间节点应该发送的。
像这样
@Start:A01:25.41,A02:36.1#@Start:A01:26.18,A02:38.2#
很多编程语言提供类似 ReadTo() 方法,意思是这个方法不返回,一直读到指定的字符时返回,所以 ReadTo(“#”) 就会返回一条完整的数据。 但是由于存在补发数据的情况,所以得循环调用这个方法像这样
for{
string 完整的数据 =ReadTo(“#”)
开始处理完整的数据的函数(完整的数据)
}
你们发现没有,由于我根本不知道客户端会有多少个完整的数据的指示符,所以我的服务端必须要循环调用 ReadTo(“#”) 并且我根本不知道什么时候该退出循环。
也就无法向 TCP 客户端发送 @Received 让来客户端断开连接。
现在就变成了,我根本不知道何时结束循环也就无法发送 @Received,而客户端也在等待我给它指示断开的指令,这样面临一个类似“死锁”状态。
这里只讨论 ReadTo(“#”) 这个方法
所以我的看法就,TCP 客户端应该将多条补发数据的格式修改为
@Start:A01:25.41,A02:36.1;@Start:A01:26.18,A02:38.2#
将中间的 #号修改为 ; 号,这样的话, 我都不需要使用循环来读。
请问,我的想法有没有考虑不周全的地方?感谢大家指正。
他们设计的协议是基于文本的,类似以下格式
@Start:A01:25.41,A02:36.1#
其中#号表示一条完整的可解析的数据的结尾,同时 TCP 客户端要求当服务器收到一条完整的数据后,要回复 @Received 用于表示接收到这条数据。
并且客户端会等待我的这个回复,才会断开 TCP 客户端一侧的连接,十几秒都没有收到则主动断开。(我们不考虑它主动断开的情况)
如果服务端没有回复,则到下一个通讯时间节点时,再次将前面没有收到回复的数据补发,然后再接着发送当前时间节点应该发送的。
像这样
@Start:A01:25.41,A02:36.1#@Start:A01:26.18,A02:38.2#
很多编程语言提供类似 ReadTo() 方法,意思是这个方法不返回,一直读到指定的字符时返回,所以 ReadTo(“#”) 就会返回一条完整的数据。 但是由于存在补发数据的情况,所以得循环调用这个方法像这样
for{
string 完整的数据 =ReadTo(“#”)
开始处理完整的数据的函数(完整的数据)
}
你们发现没有,由于我根本不知道客户端会有多少个完整的数据的指示符,所以我的服务端必须要循环调用 ReadTo(“#”) 并且我根本不知道什么时候该退出循环。
也就无法向 TCP 客户端发送 @Received 让来客户端断开连接。
现在就变成了,我根本不知道何时结束循环也就无法发送 @Received,而客户端也在等待我给它指示断开的指令,这样面临一个类似“死锁”状态。
这里只讨论 ReadTo(“#”) 这个方法
所以我的看法就,TCP 客户端应该将多条补发数据的格式修改为
@Start:A01:25.41,A02:36.1;@Start:A01:26.18,A02:38.2#
将中间的 #号修改为 ; 号,这样的话, 我都不需要使用循环来读。
请问,我的想法有没有考虑不周全的地方?感谢大家指正。
大佬有話說 (21)