网络编程
网络协议
TCP(传输控制协议)和UDP(用户数据报协议)是互联网中两种核心的 传输层协议,用于在设备间传输数据。
TCP
特点:
- 面向连接:通信前需要通过三次握手建立连接,结束后通过四次挥手断开;
- 可靠传输:通过确认应答、重传机制、数据排序等确保数据完整有序到达;
- 顺序控制:它会保证数据包按顺序到达,接收方会根据序列号进行排序;
- 流量控制和拥塞控制:TCP具有流量控制和拥塞控制功能,以防止网络堵塞;
适用场景:
- 对可靠性要求高的应用,如网页浏览、文件传输、邮件服务。
三次握手
三次握手是客户端与服务器建立连接的过程,它保证了通信双方建立一个可靠的连接。
- 第一次握手:客户端向服务器发送一个 SYN 包,其中包含客户端的初始序列号,表示请求建立连接;
- 第二次握手:服务器收到 SYN 包后,会向客户端发送一个 SYN/ACK 包,其中包含服务器的初始序列号和对客户端序列号的确认;
- 第三次握手:客户端收到 SYD/ACK 包后,会向服务器发送一个 ACK 包,其中包含对服务器序列号的确认;
四次挥手
四次挥手用于在客户端和服务器之间断开一个连接。
- 第一次挥手:客户端向服务器发送一个 FIN 包,表示客户端已经没有数据要发送了;
- 第二次挥手:服务器收到 FIN 包后,会向客户端发送一个 ACK 包,表示服务器已经收到了客户端的 FIN 包;
- 第三次挥手:服务器向客户端发送一个 FIN 包,表示服务器已经没有数据要发送了;
- 第四次挥手:客户端收到 FIN 包后,会向服务器发送一个 ACK 包,表示客户端已经收到了服务器的 FIN 包;
UDP
特点:
- 无连接:UDP是一种无连接的协议,发送数据之前不需要建立连接,数据包独立传输;
- 不可靠:UDP不保证数据包的到达,也不保证顺序,丢失都得数据包不会重新传输;
- 传输效率高:因为没有建立连接和维护状态,它比TCP更轻量,传输效率较高;
适用场景:
- 适用于对实时性要求高,容忍丢包的应用,如视频流、在线游戏、语音通话等;
TCP使用
服务端
java
public static void main(String[] args) throws IOException {
System.out.println("服务端已启动,等待客户端连接...");
// 创建 ServerSocket 对象,并指定端口
ServerSocket serverSocket = new ServerSocket(6666);
// 服务端等待客户端连接(这里会阻塞程序)
Socket accept = serverSocket.accept();
// 读取客户端发送过来的数据
InputStream inputStream = accept.getInputStream();
byte[] bytes = new byte[1024];
int len = inputStream.read(bytes);
System.out.println("收到客户端消息:" + new String(bytes, 0, len));
// 向客户端回复数据
OutputStream outputStream = accept.getOutputStream();
outputStream.write("给你10个大电影,注意身体!".getBytes());
// 释放资源
serverSocket.close();
accept.close();
inputStream.close();
outputStream.close();
}
客户端
java
public static void main(String[] args) throws IOException {
// 创建 socket 对象,指定IP和端口号
Socket socket = new Socket("127.0.0.1", 6666);
// 向服务端发送数据
OutputStream outputStream = socket.getOutputStream();
outputStream.write("我想下载两个小电影".getBytes());
// 接收服务端回复的数据
InputStream inputStream = socket.getInputStream();
byte[] bytes = new byte[1024];
int len = inputStream.read(bytes);
System.out.println(new String(bytes, 0, len));
// 释放资源
socket.close();
outputStream.close();
inputStream.close();
}
UDP使用
服务端
java
public static void main(String[] args) throws IOException {
System.out.println("UDP服务端已启动,等待客户端发送消息...");
// 创建UDP socket,监听端口为 6666
DatagramSocket socket = new DatagramSocket(6666);
// 接收客户端数据
byte[] bytes = new byte[1024];
DatagramPacket packet = new DatagramPacket(bytes, bytes.length);
socket.receive(packet);
// 解析数据
byte[] data = packet.getData();
int length = packet.getLength();
System.out.println("收到服务端消息:" + new String(data, 0, length));
InetAddress address = packet.getAddress();
int port = packet.getPort();
System.out.println("IP:" + address + ":" + port);
// 释放资源
socket.close();
}
客户端
java
public static void main(String[] args) throws IOException {
// 创建 DatagramSocket 对象
DatagramSocket socket = new DatagramSocket();
// 创建 DatagramPacket 对象,将数据进行打包
byte[] bytes = "你好啊".getBytes();
InetAddress ip = InetAddress.getByName("127.0.0.1");
int port = 6666;
DatagramPacket packet = new DatagramPacket(bytes, bytes.length, ip, port);
// 发送数据
socket.send(packet);
// 释放资源
socket.close();
}
java
public static void main(String[] args) throws IOException {
// 创建 DatagramSocket 对象
DatagramSocket socket = new DatagramSocket();
// 创建 DatagramPacket 对象,将数据进行打包
byte[] bytes = "你好啊".getBytes();
InetAddress ip = InetAddress.getByName("127.0.0.1");
int port = 6666;
DatagramPacket packet = new DatagramPacket(bytes, bytes.length, ip, port);
// 发送数据
socket.send(packet);
// 释放资源
socket.close();
}