Socket,也叫套接字..emmmmm…. 。


三次握手

socket通信的连接可分为四个步骤:

服务器监听:

服务器实时监控网络,等待客户端的连接。

客户端请求:

客户端发出了请求,向服务器提出连接请求,连接要提供ip+端口。

服务器确认连接:

服务器接收到了来自客户端的请求,它会新建一个线程,将套接字的描述发送给客户端。

客户端连接确认

一旦客户确认了来自服务器的描述,连接就建立好了。双方开始进行通信。

除去第一个,后面的三个步骤也叫三次握手。


四次挥手

客户端挥手:

客户端向服务器表示,已经没有数据发送了。

服务器确认:

服务器接收到客户端的挥手请求后,向服务器表示同意挥手。

服务器端也向客户端挥手:

服务器向客户端表示,我也没有数据要发送了。

客户端确认:

客户端接收到服务器的挥手请求后,向客户端表示同意挥手。


emmmmm….
我想听一个 TCP 的笑话。

你好,你想听 TCP 的笑话么?

嗯,我想听一个 TCP 的笑话。

好的,我会给你讲一个TCP 的笑话。

好的,我会听一个TCP 的笑话。

你准备好听一个TCP 的笑话么?

嗯,我准备好听一个TCP 的笑话

Ok,那我要发 TCP 笑话了。大概有 10 秒,20 个字。

嗯,我准备收你那个 10 秒时长,20 个字的笑话了。


BIO

BIO是同步阻塞的通信,如果有100个人想听TCP笑话,就必须有100个人去讲笑话,即使这个笑话还没真正开始讲。
最传统的JAVA BIO中有两个角色,客户端Socket,服务器ServerSocket。

使用方式非常简单,服务器只需要new一个ServerSocket,然后等待客户端来通信就行。

ServerSocket server = new ServerSocket(PORT);
            System.out.println("开始连接");
            Socket socket = server.accept();
            new Thread(new ServerHandler(socket)).start();

// ServerHandler中的run方法

            BufferedReader in = new BufferedReader(new InputStreamReader(this.socket.getInputStream()));
            PrintWriter out = new PrintWriter(this.socket.getOutputStream(), true);
            String body;

            while (true) {
                body = in.readLine();
                if (body == null) break;
                System.out.println("服务器从客户端那里收到了:" + body);
                out.println("服务器响应收到了!这是通知!" + System.currentTimeMillis());
            }

客户端只需要new一个Socket,直接进行通信。

Socket socket = new Socket(ADDRESS, PORT);
            in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            out = new PrintWriter(socket.getOutputStream(), true);

            out.println("客户端 [" + i + "] 发出一条数据!" + System.currentTimeMillis());
            String res = in.readLine();
            System.out.println("客户端 [" + i + "] 收到的数据是:" + res);

如果没有使用 new Thread(new ServerHandler(socket)).start();,那么这个服务器和客户端就是全同步的,new一个线程后,实现了伪异步..在建立连接后,在服务器上只有这个参与通信的线程与客户端互相阻塞。

而且每个客户端会在服务器端对应一个线程,对服务器来说也是不小的压力。

待续……


抱歉,你的连接超时了。你好,你想听 TCP 的笑话么 。