对方通过单片机使用 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#
将中间的 #号修改为 ; 号,这样的话, 我都不需要使用循环来读。
请问,我的想法有没有考虑不周全的地方?感谢大家指正。
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
https://www.v2ex.com/t/814687
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.