java自定义协议

    在设计 C-S 结构的应用时,我们一般需要使用一种客户端C与服务端S的通信协议。现在常用的协议有HTTP,XML-RPC,SOAP等,当然,现在XML在很多场景下都用JSON替代了,这个不赘述,有些时候,我们需要设计一些自有协议,这里咱们就说一下设计自有协议时需要注意的几个点:

1、C-S交互

    客户端与服务器之间通过信息(数据)交换来完成具体操作,举例来说,当客户端向服务器发送一个请求来执行某个操作,服务器在执行完成后向客户端回复一个处理结果,这是客户端与服务端的一次完整交互。

    当一台ComputerA向另一台ComputerB 通过网络发送信息,从A发出信息到B接收到信息需要花费一定的时间,这个网络传输时间称为时延。

在定义协议时,完成某操作需要的交互次数越多,协议的效率就越低,如果时延很高,那效率低下就会更明显。HTTP协议完成一次操作时,只需要一次请求与一次响应,也就是只需要一次交互。而SMTP在完成一次邮件发送前会经过多次交互。

    我们只有在客户端需要向服务端发送大量的数据时,才考虑将协议操作拆分为多次交互。我们一般有两种选择:

1、使用一次单独的交互来发送头信息

2、将信息拆分为多个信息块

    如果服务器可以对头信息做一些初始化的预先校验,那在第一次交互时发送头信息是比较好的选择,如果头信息无效,即时数据被正常接收也是无效的。

    在传输大体量的数据时,如果中途网络连接断开,我们需要将所有数据从新发送,但如果我们将数据拆分为小的数据块,那么当网络连接失败时,我们只需要从新发送失败的数据块,然后就可以go on,已经发送成功的数据块就不需要重新发送。

2、多请求与多响应的划分

    当通过相同连接发送多个请求时,我们需要划分出不同的请求,同时,客户端也需要划分开不同的响应。针对此问题,我们一般有两种选择:

1、在请求信息的开始部分标明信息的字节长度

2、在请求内容后添加结束标识

    HTTP使用的是第一种,在请求头中通过“Content-Length”标识请求数据的字节长度。它标识了请求头后有多少字节属于这个请求。这种方式相较第二种优点是减少结束符处理开销的同时,也不需要对原始信息中可能存在的与结束符相同的字符进行转义操作。缺点就是,我们在数据发送之前必须知道数据的长度,如果数据是动态生成的,我们需要缓存整个请求数据,在获取数据长度之后才能执行发送操作。

    使用结束符是,我们不必要知道我们发送的数据有多长,我们只需要在待发送数据的尾部加上结束符,但是我们需要对数据体中可能混淆结束符的字符进行转义。

3、防火墙穿透

    大多数防火墙会阻止HTTP以外的协议通信,所以我们构建网络通信协议时基于HTTP组建新协议是一个比较好的办法。我们需要在HTTP请求及响应信息的内部来构建我们的协议。我们构建的协议形式可以是文本,可以是xml,也可以是二进制。但因为HTTP的特殊性,我们在组建某些协议时会有一定的额外开销。

你可能感兴趣的:(随笔)