网络协议的设计(积累改进中)
2015-04-22 17:11
323 查看
做一个稍微复杂一点的APP都要涉及网络,网络通讯简单一点的是使用HTTP协议,HTTP协议是PULL的,我也蛮喜欢HTTP的,因为简单。对于需要大量交互的应用还是要用socket,所以基本上还是要自己制订协议,做过几个应用都有用到这方便的东西,所以也想总结一下,由于自己的知识有限,随着学到的东西越来越多,可能会发现这篇文章有一些错误或者需要改进的地方,我会随时更新。
协议的字段
先说说我认为一个协议必要的几个字段:
1、长度字段
TCP是一个流协议,我们想要发送一个包时,会将数据写入TCP的发送缓冲区中,至于TCP怎样发送,这是与TCP的实现和网络状况相关的,接收端收到可读通知可能一次从接收缓冲区读一部分数据也可能是全部数据,这都是不确定的。所以每一个协议都要有一个长度字段,这样接收端就可以知道某一个包是从何时开始从何时结束的,从而正确解析这个包。
2、transition id
我们把这个字段叫做事务id,为什么需要这个字段呢?
一般来说,我们发送给服务器的包,都想要服务器有一个回应,那么如何标志这个请求对应的是哪一个回应呢,使用的就是事务id,当然可能有人会说tcp是保证发包的顺序的,如果两个请求发出去然后收到两个回应的顺序应该是一样的,这样的说法虽然正确,但是它依赖于服务器的逻辑,虽然服务器收到的请求是按照顺序的,但是服务器的响应未必先返回最先接收的包;另外就是这样做客户端的逻辑处理会很麻烦,所以个人觉得事务id是很有必要的。
服务端发送的响应包也要有事务id字段,并且要与客户端请求包中的事务id相同。
3、协议的命令字段
这个字段是必须的,它标志各种不同的协议,对于即时通讯的应用,涉及到好多逻辑,比如发送消息的请求、加好友的请求、删除好友的请求等等,区分这些协议的就是这个命令字段。
4、协议的版本号
需求是不断变化的,所以协议很有可能会更改,增加一个版本号字段有利于区分协议的版本,为了能够向下兼容。
协议的类型
协议有几种类型:1、请求;2、响应;3、通知。请求是客户端发送给服务器的,响应是对应于请求包,服务器给客户端发送的响应包;通知则是服务器主动发送给客户端的包,用来通知某一个事件的发生。以即时通讯中发送文本消息为例,用户A发送文本消息给用户B,用户A发送文本消息给服务器的包就是请求包,服务器收到后要回应用户A服务器已经收到请求,这就是回应包,然后服务器需要通知用户B有文本消息,这就是通知包。
在设计协议时,我认为每一个请求,都要对应一个应答,我们称作ACK(ackownledge),理由是:虽然TCP可以保证可靠的交付,不过网络随时可能断开,当客户端检测到网络断开时,从实现角度来看客户端并不知道我们send成功的请求是否已经到达服务器(socket编程中,send成功只表示数据被成功写入tcp的发送缓冲区)。
以即时通讯应用发送文本消息为例,当用户输入一些文本,点击发送后,客户端应该先把这条消息存入数据库,UI上显示的是消息发送中,然后在网络层发送这个发送消息的请求包,等待服务器的ACK,服务器的ACK到来后,客户端更新数据库为消息发送成功,然后更新UI。有一种情况是ACK迟迟不会来,客户端需要有一个超时机制,当超时后,更新数据库标识消息已经超时,然后更新UI。当然在ACK回来之前,网络可能断开,此时相当于超时的处理逻辑。
协议的字段
先说说我认为一个协议必要的几个字段:
1、长度字段
TCP是一个流协议,我们想要发送一个包时,会将数据写入TCP的发送缓冲区中,至于TCP怎样发送,这是与TCP的实现和网络状况相关的,接收端收到可读通知可能一次从接收缓冲区读一部分数据也可能是全部数据,这都是不确定的。所以每一个协议都要有一个长度字段,这样接收端就可以知道某一个包是从何时开始从何时结束的,从而正确解析这个包。
2、transition id
我们把这个字段叫做事务id,为什么需要这个字段呢?
一般来说,我们发送给服务器的包,都想要服务器有一个回应,那么如何标志这个请求对应的是哪一个回应呢,使用的就是事务id,当然可能有人会说tcp是保证发包的顺序的,如果两个请求发出去然后收到两个回应的顺序应该是一样的,这样的说法虽然正确,但是它依赖于服务器的逻辑,虽然服务器收到的请求是按照顺序的,但是服务器的响应未必先返回最先接收的包;另外就是这样做客户端的逻辑处理会很麻烦,所以个人觉得事务id是很有必要的。
服务端发送的响应包也要有事务id字段,并且要与客户端请求包中的事务id相同。
3、协议的命令字段
这个字段是必须的,它标志各种不同的协议,对于即时通讯的应用,涉及到好多逻辑,比如发送消息的请求、加好友的请求、删除好友的请求等等,区分这些协议的就是这个命令字段。
4、协议的版本号
需求是不断变化的,所以协议很有可能会更改,增加一个版本号字段有利于区分协议的版本,为了能够向下兼容。
协议的类型
协议有几种类型:1、请求;2、响应;3、通知。请求是客户端发送给服务器的,响应是对应于请求包,服务器给客户端发送的响应包;通知则是服务器主动发送给客户端的包,用来通知某一个事件的发生。以即时通讯中发送文本消息为例,用户A发送文本消息给用户B,用户A发送文本消息给服务器的包就是请求包,服务器收到后要回应用户A服务器已经收到请求,这就是回应包,然后服务器需要通知用户B有文本消息,这就是通知包。
在设计协议时,我认为每一个请求,都要对应一个应答,我们称作ACK(ackownledge),理由是:虽然TCP可以保证可靠的交付,不过网络随时可能断开,当客户端检测到网络断开时,从实现角度来看客户端并不知道我们send成功的请求是否已经到达服务器(socket编程中,send成功只表示数据被成功写入tcp的发送缓冲区)。
以即时通讯应用发送文本消息为例,当用户输入一些文本,点击发送后,客户端应该先把这条消息存入数据库,UI上显示的是消息发送中,然后在网络层发送这个发送消息的请求包,等待服务器的ACK,服务器的ACK到来后,客户端更新数据库为消息发送成功,然后更新UI。有一种情况是ACK迟迟不会来,客户端需要有一个超时机制,当超时后,更新数据库标识消息已经超时,然后更新UI。当然在ACK回来之前,网络可能断开,此时相当于超时的处理逻辑。
相关文章推荐
- 网络协议及网络软件框架设计
- 优雅设计封装基于Okhttp3的网络框架(一):Http网络协议与Okhttp3解析
- 网络通信中的协议设计
- 网络协议设计的一点思考
- 【2017网络协议编程与分析课程设计】(一)开始写程序之前的一些准备
- 实时游戏的网络协议设计(转)
- 网络编程中应用层(基于TCP/UDP)的协议设计
- 用C#设计一个基于UDP协议的简单网络聊天器
- 网络协议设计的一点思考
- 网络协议解析数据设计和excel辅助生成代码
- 计算机网络- 可靠数据传输协议-设计和实施的协议,如停止的
- 网络游戏协议以及分发模块的设计
- 网络协议设计
- 造轮子 | 怎样设计一个面向协议的 iOS 网络请求库
- 网络协议安全设计的现场指南
- 用Java做网络协议设计
- 谈谈网络编程中应用层(基于TCP/UDP)的协议设计 [帧设计]
- 我的IM - 基础篇[3] - 基于UDP通讯的IM设计[基于XML格式的网络通讯协议 以及 包解析器和包处理器的基础概念] 【转载】
- 网络协议及网络软件框架设计
- 谈谈网络编程中应用层(基于TCP/UDP)的协议设计