网络套接字

一、网络资源
什么是网络资源?

  • 网络资源 = 网络中可供访问、使用、共享的所有信息、服务、硬件、数据的总称。
  • 生活例子:
    • 把 互联网 = 一座超级大商场
    • 你 = 电脑 / 手机
    • 网线 / WiFi = 路
    • IP 地址 = 商场地址 + 店铺门牌号
    • Socket = 你走进店里、和店员说话的通道 / 手
    • 网络资源 = 商场里所有能被你使用的东西
    • 商品(图片、视频、文件)
    • 服务(吃饭、理发、咨询)
    • 位置、通道、设备
    • 一句话:你在网络上能访问、下载、使用的一切,都叫网络资源。
  • 所有的⽹络资源,都是通过⽹络编程来进⾏数据传输的。

二、网络编程
1.什么是网络编程?

  • 网络编程 = 写代码,让程序通过网络和别的程序通信。
  • 利用操作系统提供的 Socket(套接字) 接口,编写程序,实现跨主机、跨进程的数据交换。
  • 简单说:让程序能 “上网”、能和别人说话
    • 普通编程:自己在家自言自语
    • 网络编程:打电话、发消息、和别人聊天
    • Socket:就是电话

2.网络编程在干什么?
做三件事:

  • 建立连接(找到对方:IP + 端口)
  • 发送 / 接收数据(通过 Socket 收发消息)
  • 关闭连接

3. 发送端和接收端
在⼀次⽹络数据传输时:
发送端: 数据的发送⽅进程,称为发送端。发送端主机即⽹络通信中的源主机。
接收端: 数据的接收⽅进程,称为接收端。接收端主机即⽹络通信中的⽬的主机。
收发端: 发送端和接收端两端,也简称为收发端。
注意: 发送端和接收端只是相对的,只是⼀次⽹络数据传输产⽣数据流向后的概念。

4.请求和响应
⼀般来说,获取⼀个⽹络资源,涉及到两次⽹络数据传输:
• 第⼀次: 请求数据的发送
• 第⼆次: 响应数据的发送。
好⽐在快餐店点⼀份炒饭:
• 先要发起请求:点⼀份炒饭
• 再有快餐店提供的对应响应:提供⼀份炒饭
在这里插入图片描述

5.客户端和服务端
服务端: 在常⻅的⽹络数据传输场景下,把提供服务的⼀⽅进程,称为服务端,可以提供对外服务。
客⼾端: 获取服务的⼀⽅进程,称为客⼾端。
对于服务来说,⼀般是提供:
• 客⼾端获取服务资源
在这里插入图片描述
• 客⼾端保存资源在服务端

在这里插入图片描述


三、网络套接字(Socket)

  1. Socket 本质
    • Socket套接字,是由系统提供⽤于⽹络通信的技术,是基于TCP/IP协议的⽹络通信的基本操作单元。
    • 基于Socket套接字的⽹络程序开发就是⽹络编程。
    • 网络编程接口,让不同主机的进程能互相通信,是应用层和传输层的桥梁。
    • 公式:Socket = (协议, 本地IP, 本地端口, 远端IP, 远端端口)
  2. 分类
套接字类型对应传输层协议核心特点数据传输特征缓冲区数据大小限制补充说明
流套接字TCP(传输控制协议)1. 有连接 2. 可靠传输 3. 面向字节流基于 IO 流传输,数据无边界可多次发送、多次分开接收有接收缓冲区有发送缓冲区大小不限传输稳定,适合文件、网页等数据传输
数据报套接字UDP(用户数据报协议)1. 无连接 2. 不可靠传输 3. 面向数据报数据一块一块传输必须一次发送、一次完整接收有接收缓冲区无发送缓冲区一次最多传输 64K传输速度快,适合直播、游戏等场景
原始套接字自定义传输层协议可读写内核未处理的 IP 协议数据自定义协议报文传输--不做重点学习,仅作了解
  1. TCP vs UDP(核心区别)
特性TCPUDP
连接面向连接(必须先建立连接)无连接(直接发数据)
可靠性可靠(不丢包、不乱序、重传)不可靠(可能丢包、乱序)
速度慢快
开销大小
适用场景文件传输、网页、数据库直播、游戏、DNS、视频通话
通信模式字节流数据报
  1. 通信流程
    TCP:服务端(创建→绑定→监听→接收→收发→关闭);客户端(创建→连接→收发→关闭)
    UDP:无连接,直接收发数据,无需监听 / 连接

四、代码编写
① BIO(同步阻塞,基础版)
TCP 服务端

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

// TCP BIO服务端
public class TCPServer {
    public static void main(String[] args) {
        try (ServerSocket serverSocket = new ServerSocket(8888)) {
            System.out.println("服务端已启动,等待连接...");
            Socket socket = serverSocket.accept(); // 阻塞等待连接
            BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
            
            String msg;
            while ((msg = in.readLine()) != null) {
                System.out.println("客户端:" + msg);
                out.println("已收到:" + msg);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

TCP 客户端

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;

// TCP BIO客户端
public class TCPClient {
    public static void main(String[] args) {
        try (Socket socket = new Socket("127.0.0.1", 8888);
             Scanner sc = new Scanner(System.in)) {
            PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
            BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            
            while (true) {
                System.out.print("客户端:");
                String msg = sc.nextLine();
                out.println(msg);
                if (msg.equals("exit")) break;
                System.out.println("服务端:" + in.readLine());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

② NIO(同步非阻塞,多路复用)
Java NIO 核心:Channel(通道)、Buffer(缓冲区)、Selector(选择器)

import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;

// TCP NIO服务端
public class NIOServer {
    public static void main(String[] args) throws Exception {
        // 1. 创建通道
        ServerSocketChannel serverChannel = ServerSocketChannel.open();
        serverChannel.configureBlocking(false); // 非阻塞
        serverChannel.bind(new InetSocketAddress(8888));
        System.out.println("NIO服务端已启动");
        
        // 2. 等待连接
        SocketChannel clientChannel = serverChannel.accept();
        if (clientChannel != null) {
            clientChannel.configureBlocking(false);
            ByteBuffer buffer = ByteBuffer.allocate(1024);
            clientChannel.read(buffer);
            buffer.flip();
            System.out.println("客户端:" + new String(buffer.array(), 0, buffer.limit()));
            clientChannel.close();
        }
        serverChannel.close();
    }
}

③ AIO(异步非阻塞,高性能)
Java AIO 核心:异步操作,完成后主动通知

import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.util.concurrent.TimeUnit;

// TCP AIO服务端
public class AIOServer {
    public static void main(String[] args) throws Exception {
        AsynchronousServerSocketChannel serverChannel = AsynchronousServerSocketChannel.open();
        serverChannel.bind(new InetSocketAddress(8888));
        System.out.println("AIO服务端已启动");
        
        // 异步接收连接
        serverChannel.accept(null, new java.nio.channels.CompletionHandler<>() {
            @Override
            public void completed(java.nio.channels.AsynchronousSocketChannel clientChannel, Object attachment) {
                serverChannel.accept(null, this); // 继续接收新连接
                ByteBuffer buffer = ByteBuffer.allocate(1024);
                clientChannel.read(buffer, buffer, new java.nio.channels.CompletionHandler<>() {
                    @Override
                    public void completed(Integer len, ByteBuffer buf) {
                        buf.flip();
                        System.out.println("客户端:" + new String(buf.array(), 0, len));
                    }
                    @Override
                    public void failed(Throwable exc, ByteBuffer buf) {}
                });
            }
            @Override
            public void failed(Throwable exc, Object attachment) {}
        });
        TimeUnit.HOURS.sleep(1); // 保持程序运行
    }
}

五、面试高频题(100% 命中)

  1. 基础必问
  • 什么是 Socket?
    答:Socket 是进程间网络通信的接口,封装了 IP、端口、协议,实现跨主机数据传输。
  • TCP 和 UDP 的区别?
    答:TCP 面向连接、可靠、慢;UDP 无连接、不可靠、快(结合表格回答)。
  • TCP 三次握手、四次挥手?
    • 三次握手:客户端→SYN→服务端→SYN+ACK→客户端→ACK→建立连接
    • 四次挥手:客户端→FIN→服务端→ACK→服务端→FIN→客户端→ACK→断开连接
  1. 进阶必问
  • BIO、NIO、AIO 的区别?
    • BIO:同步阻塞,一个连接一个线程,并发低
    • NIO:同步非阻塞,多路复用,一个线程处理多个连接
    • AIO:异步非阻塞,无需轮询,操作系统完成后通知
  • Socket 粘包 / 拆包问题?
    • 原因:TCP 是字节流,无边界,数据合并 / 拆分传输
    • 解决:固定长度、分隔符、消息头 + 消息体
  • 端口号范围?
    • 0 ~ 1023:知名端口(HTTP80、HTTPS443);1024~65535:自定义端口
  1. 实战问题
  • Socket 服务端如何实现高并发?
    答:使用 NIO/AIO、线程池、多路复用器(Selector)
  • UDP 如何实现可靠传输?
    答:应用层手动实现确认机制、重传、序号(如 QUIC 协议)
Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐