最近在看《http 权威指南》,个人 认为还是很值得一读,但是书很贵,花了哥80多大洋!实在心疼。
园子里有很多优秀的文章介绍http协议,http的请求流程说的很粗糙,就像下图:
这个流程隐藏很多细节,下面听我扯扯。
可以看出,HTTP是基于传输层的TCP协议,而TCP是一个端到端的面向连接的协议。所谓的端到端可以理解为进程到进程之间的通信。所以HTTP在开始传输之前,首先需要建立TCP连接,而TCP连接的过程需要所谓的"三次握手":
何为三次握手:
第一次 : 请求新的TCP连接时,客户端要向服务器发送一个小的TCP分组(通常是40~60个字节)。在这个分组中设置了一个特殊的SYN标记,说明是一个连接请求。
第二次: 如果服务器接受连接,就会对一些连接的参数进行计算,并向客户端回送一个TCP的分组,这个分组中的SYN和ACK标记都被置位,说明请求已经被接受。
第三次: 最后客户端向服务器发送一条确认信息,通知它连接已经成功建立。
完成三次握手,就可以传送数据。 这个过程和打电话很相似。 A: hi,你是小丽吗? B: 是的 A: 哦,我是xx屌丝! 然后进行。。。。!下图展示了此过程
TCP是安全的,但是握手花去了很多的时间。
TCP的socket编程
通过socket连接客户端与服务端进行通信,用下面的代码模拟一下
server端
import java.net.*; import java.io.*; public class TestServer { public static void main(String args[]) { try { ServerSocket s = new ServerSocket(8888); while (true) { Socket s1 = s.accept(); OutputStream os = s1.getOutputStream(); DataOutputStream dos = new DataOutputStream(os); dos.writeUTF("Hello"); dos.close(); s1.close(); } }catch (IOException e) { e.printStackTrace(); System.out.println("程序运行出错:" + e); } } }
Client 端
import java.net.*; import java.io.*; public class TestClient { public static void main(String args[]) { try { Socket s1 = new Socket("127.0.0.1", 8888); InputStream is = s1.getInputStream(); DataInputStream dis = new DataInputStream(is); System.out.println(dis.readUTF()); dis.close(); s1.close(); } catch (ConnectException connExc) { connExc.printStackTrace(); System.err.println("服务器连接失败!"); } catch (IOException e) { e.printStackTrace(); } } }
先运行 TestServer,就会不断的监听8888端口,当有一个Client连过来,就会输出hello,客户端就会接受到hello!
下图展示了我最想说的内容,一切尽在图中。
不好意思,有很多英文。还好都是常见的!