概述
TCP和UDP是传输层的协议,其中TCP 是面向连接的协议,通信前需要建立连接,通信结束后需要断开连接。 连接建立和断开过程比较复杂,涉及到三次握手和四次挥手。 UDP 是无连接的协议,通信前不需要建立连接,通信结束后也不需要断开连接。
可靠性方面TCP 提供可靠的数据传输,通过序号、确认和重传机制保证数据的可靠性。数据丢失会自动重新传递数据确保数据的完整性和顺序性。UDP 不提供可靠性保证,不会自动进行数据重传。
在Java中实现TCP和UDP通信,你可以使用java.net包中的ServerSocket、Socket类来实现TCP服务器和客户端,以及使用DatagramSocket、DatagramPacket类来实现UDP通信。
TCP
TCP服务端
import java.io.*;
import java.net.*;
public class TCPServer {
public static void main(String[] args) {
int port = 12345; // 定义端口号
try (ServerSocket serverSocket = new ServerSocket(port)) {
System.out.println("服务器启动,等待连接...");
Socket socket = serverSocket.accept(); // 接受客户端连接
System.out.println("客户端已连接");
// 读取客户端数据
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null) {
System.out.println("收到客户端消息: " + inputLine);
// 响应客户端
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
out.println("服务器响应: " + inputLine);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
TCP客户端
import java.io.*;
import java.net.*;
public class TCPClient {
public static void main(String[] args) {
String hostname = "localhost"; // 服务器地址
int port = 12345; // 服务器端口号
try (Socket socket = new Socket(hostname, port)) {
// 发送数据到服务器
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader console = new BufferedReader(new InputStreamReader(System.in));
System.out.println("请输入消息发送到服务器:");
String userInput;
while (!(userInput = console.readLine()).equals("exit")) {
out.println(userInput);
// 读取服务器响应
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
System.out.println("服务器响应: " + in.readLine());
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
UDP
UDP 服务端
import java.io.*;
import java.net.*;
public class UDPServer {
public static void main(String[] args) throws IOException {
int port = 12345; // 定义端口号
DatagramSocket socket = new DatagramSocket(port); // 创建DatagramSocket对象用于接收数据包
byte[] receiveData = new byte[1024]; // 接收数据缓存区
while (true) {
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length); // 创建数据包对象用于接收数据包内容
socket.receive(receivePacket); // 接收数据包内容到receivePacket对象中
String sentence = new String(receivePacket.getData(), 0, receivePacket.getLength()); // 将接收到的数据转换成字符串形式,并打印输出到控制台。
System.out.println("收到客户端消息: " + sentence); // 打印接收到的消息内容。
String capitalizedSentence = sentence.toUpperCase(); // 将接收到的消息内容转换为大写形式。
InetAddress IPAddress = receivePacket.getAddress(); // 获取客户端的IP地址。
int portNumber = receivePacket.getPort(); // 获取客户端的端口号。
DatagramPacket sendPacket = new DatagramPacket(capitalizedSentence.getBytes(), capitalizedSentence.length(), IPAddress, portNumber); // 创建数据包对象用于发送数据包内容。
socket.send(sendPacket); // 将大写形式的数据包内容发送给客户端。
}
}
}
UDP客户端
import java.io.*;
import java.net.*;
import java.util.*;
public class UDPClient {
public static void main(String[] args) throws IOException {
String hostname = "localhost"; // 服务器地址
int port = 12345; // 服务器端口号
BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in)); // 从控制台读取输入流。
Dat