网络套接字
网络套接字
一、网络资源
什么是网络资源?
- 网络资源 = 网络中可供访问、使用、共享的所有信息、服务、硬件、数据的总称。
- 生活例子:
- 把 互联网 = 一座超级大商场
- 你 = 电脑 / 手机
- 网线 / WiFi = 路
- IP 地址 = 商场地址 + 店铺门牌号
- Socket = 你走进店里、和店员说话的通道 / 手
- 网络资源 = 商场里所有能被你使用的东西
- 商品(图片、视频、文件)
- 服务(吃饭、理发、咨询)
- 位置、通道、设备
- 一句话:你在网络上能访问、下载、使用的一切,都叫网络资源。
- 所有的⽹络资源,都是通过⽹络编程来进⾏数据传输的。
二、网络编程
1.什么是网络编程?
- 网络编程 = 写代码,让程序通过网络和别的程序通信。
- 利用操作系统提供的 Socket(套接字) 接口,编写程序,实现跨主机、跨进程的数据交换。
- 简单说:让程序能 “上网”、能和别人说话
- 普通编程:自己在家自言自语
- 网络编程:打电话、发消息、和别人聊天
- Socket:就是电话
2.网络编程在干什么?
做三件事:
- 建立连接(找到对方:IP + 端口)
- 发送 / 接收数据(通过 Socket 收发消息)
- 关闭连接
3. 发送端和接收端
在⼀次⽹络数据传输时:
发送端: 数据的发送⽅进程,称为发送端。发送端主机即⽹络通信中的源主机。
接收端: 数据的接收⽅进程,称为接收端。接收端主机即⽹络通信中的⽬的主机。
收发端: 发送端和接收端两端,也简称为收发端。
注意: 发送端和接收端只是相对的,只是⼀次⽹络数据传输产⽣数据流向后的概念。
4.请求和响应
⼀般来说,获取⼀个⽹络资源,涉及到两次⽹络数据传输:
• 第⼀次: 请求数据的发送
• 第⼆次: 响应数据的发送。
好⽐在快餐店点⼀份炒饭:
• 先要发起请求:点⼀份炒饭
• 再有快餐店提供的对应响应:提供⼀份炒饭

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

• 客⼾端保存资源在服务端

三、网络套接字(Socket)
- Socket 本质
- Socket套接字,是由系统提供⽤于⽹络通信的技术,是基于TCP/IP协议的⽹络通信的基本操作单元。
- 基于Socket套接字的⽹络程序开发就是⽹络编程。
- 网络编程接口,让不同主机的进程能互相通信,是应用层和传输层的桥梁。
- 公式:Socket = (协议, 本地IP, 本地端口, 远端IP, 远端端口)
- 分类
| 套接字类型 | 对应传输层协议 | 核心特点 | 数据传输特征 | 缓冲区 | 数据大小限制 | 补充说明 |
|---|---|---|---|---|---|---|
| 流套接字 | TCP(传输控制协议) | 1. 有连接 2. 可靠传输 3. 面向字节流 | 基于 IO 流传输,数据无边界可多次发送、多次分开接收 | 有接收缓冲区有发送缓冲区 | 大小不限 | 传输稳定,适合文件、网页等数据传输 |
| 数据报套接字 | UDP(用户数据报协议) | 1. 无连接 2. 不可靠传输 3. 面向数据报 | 数据一块一块传输必须一次发送、一次完整接收 | 有接收缓冲区无发送缓冲区 | 一次最多传输 64K | 传输速度快,适合直播、游戏等场景 |
| 原始套接字 | 自定义传输层协议 | 可读写内核未处理的 IP 协议数据 | 自定义协议报文传输 | - | - | 不做重点学习,仅作了解 |
- TCP vs UDP(核心区别)
| 特性 | TCP | UDP |
|---|---|---|
| 连接 | 面向连接(必须先建立连接) | 无连接(直接发数据) |
| 可靠性 | 可靠(不丢包、不乱序、重传) | 不可靠(可能丢包、乱序) |
| 速度 | 慢 | 快 |
| 开销 | 大 | 小 |
| 适用场景 | 文件传输、网页、数据库 | 直播、游戏、DNS、视频通话 |
| 通信模式 | 字节流 | 数据报 |
- 通信流程
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% 命中)
- 基础必问
- 什么是 Socket?
答:Socket 是进程间网络通信的接口,封装了 IP、端口、协议,实现跨主机数据传输。 - TCP 和 UDP 的区别?
答:TCP 面向连接、可靠、慢;UDP 无连接、不可靠、快(结合表格回答)。 - TCP 三次握手、四次挥手?
- 三次握手:客户端→SYN→服务端→SYN+ACK→客户端→ACK→建立连接
- 四次挥手:客户端→FIN→服务端→ACK→服务端→FIN→客户端→ACK→断开连接
- 进阶必问
- BIO、NIO、AIO 的区别?
- BIO:同步阻塞,一个连接一个线程,并发低
- NIO:同步非阻塞,多路复用,一个线程处理多个连接
- AIO:异步非阻塞,无需轮询,操作系统完成后通知
- Socket 粘包 / 拆包问题?
- 原因:TCP 是字节流,无边界,数据合并 / 拆分传输
- 解决:固定长度、分隔符、消息头 + 消息体
- 端口号范围?
- 0 ~ 1023:知名端口(HTTP80、HTTPS443);1024~65535:自定义端口
- 实战问题
- Socket 服务端如何实现高并发?
答:使用 NIO/AIO、线程池、多路复用器(Selector) - UDP 如何实现可靠传输?
答:应用层手动实现确认机制、重传、序号(如 QUIC 协议)
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)