掌握Socket编程与网络通信的核心技术和实际应用
网络编程是指编写能够在网络上进行数据通信的程序。Java提供了强大的网络编程API,使得开发网络应用变得相对简单。网络编程的核心是Socket(套接字),它是网络通信的端点。
// Socket是网络通信的端点
// 包含IP地址和端口号
// 用于建立网络连接
// 服务器:监听端口,等待连接
// 客户端:主动连接服务器
// 建立连接后进行数据交换
TCP(传输控制协议)是一种可靠的、面向连接的协议。它保证数据的完整性和顺序,适用于对数据准确性要求较高的应用。
import java.io.*;
import java.net.*;
public class TCPServer {
public static void main(String[] args) {
try {
// 创建服务器Socket,监听8080端口
ServerSocket serverSocket = new ServerSocket(8080);
System.out.println("服务器启动,监听端口8080...");
while (true) {
// 等待客户端连接
Socket clientSocket = serverSocket.accept();
System.out.println("客户端连接:" + clientSocket.getInetAddress());
// 创建新线程处理客户端请求
new Thread(new ClientHandler(clientSocket)).start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
class ClientHandler implements Runnable {
private Socket clientSocket;
public ClientHandler(Socket socket) {
this.clientSocket = socket;
}
@Override
public void run() {
try {
// 获取输入输出流
BufferedReader in = new BufferedReader(
new InputStreamReader(clientSocket.getInputStream()));
PrintWriter out = new PrintWriter(
clientSocket.getOutputStream(), true);
String inputLine;
while ((inputLine = in.readLine()) != null) {
System.out.println("收到消息:" + inputLine);
out.println("服务器回复:" + inputLine);
}
clientSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
import java.io.*;
import java.net.*;
import java.util.Scanner;
public class TCPClient {
public static void main(String[] args) {
try {
// 连接到服务器
Socket socket = new Socket("localhost", 8080);
System.out.println("连接到服务器成功!");
// 获取输入输出流
PrintWriter out = new PrintWriter(
socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
Scanner scanner = new Scanner(System.in);
String userInput;
while (true) {
System.out.print("请输入消息(输入'quit'退出):");
userInput = scanner.nextLine();
if ("quit".equalsIgnoreCase(userInput)) {
break;
}
// 发送消息到服务器
out.println(userInput);
// 接收服务器回复
String response = in.readLine();
System.out.println(response);
}
socket.close();
scanner.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
UDP(用户数据报协议)是一种无连接的协议,传输速度快但不保证数据的可靠性。适用于对实时性要求较高的应用,如视频流、游戏等。
import java.net.*;
import java.io.*;
public class UDPServer {
public static void main(String[] args) {
try {
// 创建DatagramSocket,监听9999端口
DatagramSocket socket = new DatagramSocket(9999);
System.out.println("UDP服务器启动,监听端口9999...");
byte[] buffer = new byte[1024];
while (true) {
// 创建数据包接收数据
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
socket.receive(packet);
// 获取客户端信息
String message = new String(packet.getData(), 0, packet.getLength());
InetAddress clientAddress = packet.getAddress();
int clientPort = packet.getPort();
System.out.println("收到来自 " + clientAddress + ":" + clientPort + " 的消息:" + message);
// 回复客户端
String response = "服务器收到:" + message;
byte[] responseData = response.getBytes();
DatagramPacket responsePacket = new DatagramPacket(
responseData, responseData.length, clientAddress, clientPort);
socket.send(responsePacket);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
import java.net.*;
import java.io.*;
import java.util.Scanner;
public class UDPClient {
public static void main(String[] args) {
try {
DatagramSocket socket = new DatagramSocket();
InetAddress serverAddress = InetAddress.getByName("localhost");
int serverPort = 9999;
Scanner scanner = new Scanner(System.in);
while (true) {
System.out.print("请输入消息(输入'quit'退出):");
String message = scanner.nextLine();
if ("quit".equalsIgnoreCase(message)) {
break;
}
// 发送数据到服务器
byte[] data = message.getBytes();
DatagramPacket packet = new DatagramPacket(
data, data.length, serverAddress, serverPort);
socket.send(packet);
// 接收服务器回复
byte[] buffer = new byte[1024];
DatagramPacket responsePacket = new DatagramPacket(buffer, buffer.length);
socket.receive(responsePacket);
String response = new String(responsePacket.getData(), 0, responsePacket.getLength());
System.out.println(response);
}
socket.close();
scanner.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
特性 | TCP | UDP |
---|---|---|
连接性 | 面向连接 | 无连接 |
可靠性 | 可靠传输,保证数据完整性 | 不可靠传输,可能丢失数据 |
速度 | 相对较慢 | 快速 |
数据顺序 | 保证数据顺序 | 不保证数据顺序 |
头部开销 | 20字节 | 8字节 |
适用场景 | 文件传输、网页浏览、邮件 | 视频流、游戏、DNS查询 |
import java.io.*;
import java.net.*;
import java.util.concurrent.*;
public class ThreadPoolServer {
private static final int PORT = 8080;
private static final int THREAD_POOL_SIZE = 10;
public static void main(String[] args) {
// 创建线程池
ExecutorService executor = Executors.newFixedThreadPool(THREAD_POOL_SIZE);
try {
ServerSocket serverSocket = new ServerSocket(PORT);
System.out.println("线程池服务器启动,监听端口" + PORT);
while (true) {
Socket clientSocket = serverSocket.accept();
// 将客户端处理任务提交给线程池
executor.submit(new ClientTask(clientSocket));
}
} catch (IOException e) {
e.printStackTrace();
} finally {
executor.shutdown();
}
}
}
class ClientTask implements Runnable {
private Socket clientSocket;
public ClientTask(Socket socket) {
this.clientSocket = socket;
}
@Override
public void run() {
try {
BufferedReader in = new BufferedReader(
new InputStreamReader(clientSocket.getInputStream()));
PrintWriter out = new PrintWriter(
clientSocket.getOutputStream(), true);
String inputLine;
while ((inputLine = in.readLine()) != null) {
// 处理客户端请求
String response = processRequest(inputLine);
out.println(response);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
clientSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private String processRequest(String request) {
// 模拟业务处理
return "处理结果:" + request.toUpperCase();
}
}
public class SafeNetworkClient {
public static void main(String[] args) {
// 使用try-with-resources确保资源正确关闭
try (Socket socket = new Socket("localhost", 8080);
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(
new InputStreamReader(socket.getInputStream()))) {
// 设置超时时间
socket.setSoTimeout(5000); // 5秒超时
out.println("Hello Server");
String response = in.readLine();
System.out.println("服务器回复:" + response);
} catch (SocketTimeoutException e) {
System.err.println("连接超时:" + e.getMessage());
} catch (ConnectException e) {
System.err.println("连接被拒绝:" + e.getMessage());
} catch (IOException e) {
System.err.println("网络错误:" + e.getMessage());
}
}
}
结合TCP Socket和多线程技术,可以实现一个简单的聊天室应用,支持多用户同时在线聊天。
在实际应用中,需要考虑数据加密、身份验证、防止DOS攻击等安全问题。
使用NIO(非阻塞I/O)可以进一步提高网络应用的性能和并发处理能力。