代码改变世界

http的请求流程

2013-05-17 23:58  掸尘  阅读(1920)  评论(1编辑  收藏  举报

   最近在看《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!

  下图展示了我最想说的内容,一切尽在图中。

 

不好意思,有很多英文。还好都是常见的!