一文搞懂Socket网络编程

07-19 1001阅读

🥑 一文搞懂Socket

一、什么是 Socket?

本质上就是两个进程之间的网络通信。其中一个进程必须充当服务器端,它会主动监听某个指定的端口,另一个进程必须充当客户端,它必须主动连接服务器的IP地址和指定端口,如果连接成功,服务器端和客户端就成功地建立了一个TCP连接,双方后续就可以随时发送和接收数据。

因此,当Socket连接成功地在服务器端和客户端之间建立后:

  • 对服务器端来说,它的Socket是指定的IP地址和指定的端口号;
  • 对客户端来说,它的Socket是它所在计算机的IP地址和一个由操作系统分配的随机端口号。

    二、为什么要使用 Socket?有什么作用?

    因为仅仅通过IP地址进行通信是不够的,同一台计算机同一时间会运行多个网络应用程序,例如浏览器、QQ、邮件客户端等。当操作系统接收到一个数据包的时候,如果只有IP地址,它没法判断应该发给哪个应用程序,所以,操作系统抽象出Socket接口,每个应用程序需要各自对应到不同的Socket,数据包才能根据Socket正确地发到对应的应用程序。

    三、TCP/IP 协议

    socket 是基于 tcp/ip 协议上的网络编程,下图描绘了 socket 在 osi 模型中大致的位置

    一文搞懂Socket网络编程

    从图上看,socket 抽象层位于传输层和应用层之间,使用tcp/ip中的三次握手、四次挥手进行建立连接、断开连接。

    TCP三次握手

    一文搞懂Socket网络编程

    客户端想建立连接,发送一个 SYN 包给服务端,服务端收到以后返回一个 SYN 包和 ACK 包,客户端接收到以后,发送 ACK 包到服务端,连接建立。因为这个过程中,发生了三包数据,所以叫三次握手。

    四次挥手

    一文搞懂Socket网络编程

    客户端与服务端都可发起断开连接,这里距离是客户端主动发起断开连接

    第一次挥手:客户端发一包 FIN 包,自身进入断开等待状态 1,表示要断开连接。

    第二次挥手:服务端向客户端发送一个 ACK 包,自身进入关闭等待状态,客户端进入等待状态 2,此时客户端还是可以发送消息,服务端可以接收消息。

    第三次挥手:服务端发送最终确认 FIN 包,确认是否断开连接,自身进入等待确认状态。

    第四次挥手:客户端发送 ACK 包,确认断开连接。自身进入超时等待状态,到时间关闭连接。服务端一旦收到 ACK 包,立即断开连接。「这里客户端进入超时等待状态而不是立马断开连接,是因为怕 ACK 包丢失后,服务端就一直处于等待关闭确认状态了」

    Socket 通信

    一文搞懂Socket网络编程

    根据socket 接口绘制的,结合下面的代码相互映照的看。

    🌵四、实现代码

    客户端代码

    package com.xiezc.socketdemo.client;
    import java.io.*;
    import java.net.Socket;
    import java.nio.charset.StandardCharsets;
    import java.util.Scanner;
    /**
     * SocketClient
     *
     * @author XieZhongCai
     * @version v1.0.0
     * @description 客户端代码
     * @date 2024/3/26 16:17
     **/
    public class SocketClient {
        public static void main(String[] args) throws IOException {
            Socket sock = new Socket("localhost", 6666); // 连接指定服务器和端口
            try (InputStream input = sock.getInputStream()) {
                try (OutputStream output = sock.getOutputStream()) {
                    handle(input, output);
                }
            }
            sock.close();
            System.out.println("disconnected.");
        }
        private static void handle(InputStream input, OutputStream output) throws IOException {
            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(output, StandardCharsets.UTF_8));
            BufferedReader reader = new BufferedReader(new InputStreamReader(input, StandardCharsets.UTF_8));
            Scanner scanner = new Scanner(System.in);
            System.out.println("[server] " + reader.readLine());
            while (true) {
                System.out.print(">>> "); // 打印提示
                String s = scanner.nextLine(); // 读取一行输入
                writer.write(s);
                writer.newLine();
                writer.flush();
                String resp = reader.readLine();
                System.out.println("
VPS购买请点击我

文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

目录[+]