Java网络:协议设计

时间:2020-01-09 10:36:13  来源:igfitidea点击:

如果要设计客户端-服务器系统,则可能还必须设计客户端与服务器之间的通信协议。当然,有时已经为我们确定了此协议,例如HTTP,XML-RPC(HTTP上的XML)或者SOAP(也是HTTP上的XML)。但是有时协议决定是开放的,因此让我们看一下我们在设计客户端服务器协议时可能要考虑的一些问题:

  • 客户端-服务器往返
  • 划分请求和响应的结尾
  • 穿透防火墙

客户端-服务器往返

当客户端和服务器进行通信以执行某些操作时,它们将交换信息。例如,客户端将要求执行一项服务,而服务器将尝试执行该服务,并发回一个响应,将结果告知客户端。客户端和服务器之间的这种信息交换称为往返。

客户

服务器发送请求接收响应客户端服务器往返当计算机(客户端或者服务器)通过Internet将数据发送到另一台计算机时,从发送数据到在另一端接收数据需要花费一些时间。这是花费数据通过Internet传输的时间。这个时间称为等待时间。

协议中的往返次数越多,协议变得越慢,尤其是在等待时间较长的情况下。 HTTP协议仅包含一个请求和一个执行其服务的响应。换句话说,一次往返。另一方面,SMTP协议包括在发送电子邮件之前客户端和服务器之间的多次往返。

将协议分成多个往返的唯一原因是,如果我们有大量数据要从客户端发送到服务器。在这种情况下,我们有两种选择:

  • 在单独的往返中发送标头信息。
  • 将邮件主体分成较小的块。

如果服务器可以进行一些初步的预验证,例如在单独的往返(第一个)中发送标头,则可能很聪明。标头信息。如果该标头信息无效,则无论如何发送大量数据都是浪费。

如果在传输大量数据时网络连接失败,则可能必须重新发送所有这些数据。通过将数据分解为较小的块,我们只需要从网络连接失败及以后的块中重新发送这些块。没有成功发送已成功传输的块。

划分请求和响应的结尾

如果协议允许通过同一连接发送多个请求,则服务器需要某种方式来知道一个请求何时结束以及新请求何时开始。客户端还需要知道一个响应何时结束,另一个响应何时开始。

我们可以使用两种方法来划分请求的结尾:

  • 在请求的开头发送请求的字节长度。
  • 在请求数据之后发送请求结束标记。

HTTP使用第一种机制。在请求标头之一中,发送" Content-Length"。该标头告知标头之后属于请求的字节数。

该模型的优点是我们没有请求结束标记的开销。我们也不必对数据主体进行编码,以避免数据看起来像请求结束标记。

第一种方法的缺点是,发送方必须在传输数据之前知道传输了多少字节。如果数据是动态生成的,则在发送之前必须首先缓冲所有数据,以计算字节数。

通过使用请求结束标记,我们不必知道要发送多少个字节。我们只需要在数据末尾发送一个请求结束标记。但是,我们必须确保发送的数据不包含任何可能被误认为请求结束标记的数据。这里是一种方法:

可以说请求结束标记是字节值255. 当然,数据也可以包含值255. 因此,对于包含值255的数据中的每个字节,我们都添加了一个额外的字节,也包含值255. 请求结束标记从字节值255更改为255,后跟值0。编码总结:

255 in data    --> 255, 255
end-of-request --> 255, 0

255,0序列永远不会出现在数据中,因为我们将所有255都更改为255,255. 并且255,255,0不会被误认为255,0。前255个将一起解释,后0个本身被解释。

穿透防火墙

大多数防火墙会阻止HTTP协议以外的所有其他流量。因此,最好像XML-RPC,SOAP和REST一样在HTTP之上分层协议。

为了在HTTP之上构建协议层,我们需要在HTTP请求和响应中的客户端和服务器之间来回发送数据。请记住,HTTP请求和响应不仅可以包含文本或者HTML,还可以包含更多内容。我们也可以其中发送二进制数据。

通过在HTTP协议之上分层请求,可能会有点奇怪,那就是HTTP请求必须包含"主机"标头字段。如果要在HTTP上设计P2P协议,则对等方很可能不会运行多个"主机"。在这种情况下,此必需的标头字段是不必要的开销(但很小)。