Java网络教程:Protocol Design

原文地址  译者:司余

如果设计一个客户端到服务器的系统,那么同时也需要设计客户端和服务器之间的通信协议。当然,有时候协议已经为你决定好了,比如HTTP、XML_RPC(http response 的 body 使用xml)、或者SOAP(也是http response 的 body 使用xml)。设计客户端到服务端协议的时候,一旦协议决定开启一会儿,来看一些你必须考虑的地方:

1. 客户端到服务端的往返通讯

2.区分请求结束和响应结束。

3.防火墙穿透

客户端-服务端往返


当客户端和服务端通信,执行操作时,他们在交换信息。比如,客户端执行一个服务请求,服务端尝试完成这个请求,发回响应告诉客户端结果。这种客户端和服务端的信息交换就叫做往返。示意图如下:

当一个计算机(客户端或者服务端)在网络中发送数据到另一个计算机时,从数据发送到另一端接收数据完会花费一定时间。这就是数据在网络间的传送的时间花费。这个时间叫做延迟。

协议中含有越多的往返,协议变得越慢,延迟特别高。HTTP协议只包含一个单独的响应来执行服务。换句话说就是一个单独的往返。另一方面,在一封邮件发送前,SMTP协议包含了几个客户端和服务端的往返。

在协议中有多个往返的原因是:有大量的数据从客户端发送到服务端。这种情况下你有2个选择:

1.在分开往返中发送头信息;

2.将消息分成更小的数据块。

如果服务端能完成头信息的一些初始验证 ,那么分开发送头信息是很明智的。如果头信息是空白的,发送大量数据本身就是浪费资源。

在传输大量数据时,如果网络连接失败了,得从头开始重新发送数据。数据分割发送时,只需要在网络连接失败处重新发送数据块。已经发送成功的数据块不需要重新发送。

区分请求结束和响应结束


如果协议容许在同一个连接中发送多个请求,需要一个让服务端知道当前请求何时结束、下一个请求何时开始。客户端也需要知道一个响应何时结束了,下一个响应何时开始。

对于请求有2个方法区分结束:

1.在请求的开始处发送请求的字长

2.在请求数据的最后发送一个结束标记。

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,255被理解成在一起的,0是单独的。

防火墙穿透

比起HTTP协议,大多数防火墙会拦截所有的其他通信。因此把协议放在HTTP的上层是个好方法,像XML-RPC,SOAP和REST也可以这样做。

协议置于HTTP的上层,在客户端和服务端的HTTP请求和响应中可以来回发送数据。记住,HTTP请求和响应不止包含text或者HTML。也可以在里面发送二进制数据。

将请求放置在HTTP协议上,唯一有点奇怪的是:HTTP请求必须包含一个“主机”头字段。如果你在HTTP协议上设计P2P协议,同样的人最可能不会运行多个“主机”。在这种情况下需要头字段是不必要的开销(但是个小开销)。

原创文章,转载请注明: 转载自并发编程网 – ifeve.com本文链接地址: Java网络教程:Protocol Design

时间: 2024-09-25 16:39:20

Java网络教程:Protocol Design的相关文章

Java网络教程

本系列尚未翻译完成,有兴趣参与翻译的请在本文评论处留言. 1 Java 网络教程: 基础 2 Java 网络教程: Socket 3 Java 网络教程: ServerSocket 4 Java Networking: UDP DatagramSocket 5 Java 网络教程: URL + URLConnection 6 Java网络教程:JarURLConnection 7 Java 网络教程: InetAddress 8 Java网络教程:Protocol Design 转载自 并发编程

Java 网络教程: InetAddress

Java 网络教程: InetAddress 创建一个 InetAddress 实例 InetAddress 的内部方法 InetAddress 是 Java 对 IP 地址的封装.这个类的实例经常和 UDP DatagramSockets 和 Socket,ServerSocket 类一起使用. 创建一个 InetAddress 实例 InetAddress 没有公开的构造方法,因此你必须通过一系列静态方法中的某一个来获取它的实例. <!–more–> 下面是为一个域名实例化 InetAdd

Java 网络教程: JarURLConnection

Java 网络教程: JarURLConnection Java 中 JarURLConnection 类用来链接 Java 的 Jar 包文件.一旦连接成功,你就可以获取到 Jar 包里面文件的内容. 下面是一个简单的实例: String urlString = "http://butterfly.jenkov.com/" + "container/download/" + "jenkov-butterfly-container-2.9.9-beta.j

Java网络教程-基础

原文地址   译者:贾毅  校对:方腾飞 Java提供了非常易用的网络API,调用这些API我们可以很方便的通过建立TCP/IP或UDP套接字,在网络之间进行相互通信,其中TCP要比UDP更加常用,但在本教程中我们对这两种方式都有说明. 在网站上还有其他三个与Java网络相关的教程,如下: 1.Java IO 教程 2.Java NIO 教程 3.Java服务器多线程教程 (参与翻译可以联系我们) 尽管Java网络API允许我们通过套接字(Socket)打开或关闭网络连接,但所有的网络通信均是基

Java 网络教程: ServerSocket

用java.net.ServerSocket实现java服务通过TCP/IP监听客户端连接,你也可以用Java NIO 来代替java网络标准API,这时候需要用到 ServerSocketChannel. 创建一个 ServerSocket连接 以下是一个创建ServerSocket类来监听9000端口的一个简单的代码 ServerSocket serverSocket = new ServerSocket(9000); 监听请求的连接 要获取请求的连接需要用ServerSocket.acce

Java网络教程:URL + URLConnection

原文地址  译者:梁远铭   目录 HTTP GET和POST 从URLs到本地文件 在java.net包中包含两个有趣的类:URL类和URLConnection类.这两个类可以用来创建客户端到web服务器(HTTP服务器)的连接.下面是一个简单的代码例子: URL url = new URL("http://jenkov.com"); URLConnection urlConnection = url.openConnection(); InputStream input = url

Java网络教程: InetAddress

InetAddress是ip地址的java表示方式.这个类的实例也可以用在UDP DatagramSockets.普通Socket类和ServerSocket类. 创建InetAddress实例 InetAddress没有public构造器,必须通过一系列的静态方法获取实例.下面是如何获取一个域名的InetAddress实例: 1 InetAddress address = InetAddress.getByName("jenkov.com"); 下面是如何获取匹配字符串表示ip地址的

Java网络教程:JarURLConnection

Java的JarURLConnection类用来连接Java Jar文件.一旦连接上,你可以获取Jar文件的信息.一个简单的例子如下: String urlString = "http://butterfly.jenkov.com/" + "container/download/" + "jenkov-butterfly-container-2.9.9-beta.jar"; URL jarUrl = new URL(urlString); Jar

java网络编程HttpsURLConnection

问题描述 java网络编程HttpsURLConnection 我写了一个多线程下载测试程序 照着教程做的 但运行提示错误这个语句HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();提示错误 sun.net.www.protocol.http.HttpURLConnection cannot be cast to javax.net.ssl.HttpsURLConnection其中rul 为 URL url =