Java Socket编程详解
Socket编程基础
Socket是网络通信的端点,Java通过Socket和ServerSocket类实现TCP通信。
TCP Socket详解
基本TCP客户端
import java.io.*;
import java.net.Socket;
public class BasicTcpClient {
public static void main(String[] args) {
try (Socket socket = new Socket("localhost", 8080)) {
socket.setSoTimeout(5000);
OutputStream out = socket.getOutputStream();
PrintWriter writer = new PrintWriter(out, true);
writer.println("Hello Server");
InputStream in = socket.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String response = reader.readLine();
System.out.println("服务器响应: " + response);
} catch (IOException e) {
e.printStackTrace();
}
}
}
基本TCP服务器
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class BasicTcpServer {
public static void main(String[] args) {
try (ServerSocket serverSocket = new ServerSocket(8080)) {
System.out.println("服务器启动,监听端口8080...");
while (true) {
Socket client = serverSocket.accept();
new Thread(() -> handleClient(client)).start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
private static void handleClient(Socket client) {
try (BufferedReader in = new BufferedReader(
new InputStreamReader(client.getInputStream()));
PrintWriter out = new PrintWriter(client.getOutputStream(), true)) {
String message = in.readLine();
System.out.println("收到: " + message);
out.println("Echo: " + message);
} catch (IOException e) {
e.printStackTrace();
}
}
}
多线程聊天服务器
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
public class ChatServer {
private static final Set<PrintWriter> clients = ConcurrentHashMap.newKeySet();
public static void main(String[] args) {
try (ServerSocket serverSocket = new ServerSocket(9000)) {
System.out.println("聊天服务器启动...");
while (true) {
Socket client = serverSocket.accept();
new Thread(() -> handleClient(client)).start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
private static void handleClient(Socket client) {
try (BufferedReader in = new BufferedReader(
new InputStreamReader(client.getInputStream()));
PrintWriter out = new PrintWriter(client.getOutputStream(), true)) {
clients.add(out);
String message;
while ((message = in.readLine()) != null) {
broadcast(message);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
clients.remove(client);
}
}
private static void broadcast(String message) {
for (PrintWriter client : clients) {
client.println(message);
}
}
}
文件传输
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class FileTransferServer {
public static void main(String[] args) {
try (ServerSocket serverSocket = new ServerSocket(8888)) {
System.out.println("文件传输服务器启动...");
while (true) {
Socket client = serverSocket.accept();
new Thread(() -> receiveFile(client)).start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
private static void receiveFile(Socket client) {
try (DataInputStream dis = new DataInputStream(client.getInputStream())) {
String fileName = dis.readUTF();
long fileSize = dis.readLong();
try (FileOutputStream fos = new FileOutputStream("received_" + fileName)) {
byte[] buffer = new byte[4096];
long remaining = fileSize;
int read;
while (remaining > 0 &&
(read = dis.read(buffer, 0, (int) Math.min(buffer.length, remaining))) != -1) {
fos.write(buffer, 0, read);
remaining -= read;
}
}
System.out.println("文件接收完成: " + fileName);
} catch (IOException e) {
e.printStackTrace();
}
}
}
class FileTransferClient {
public static void main(String[] args) {
try (Socket socket = new Socket("localhost", 8888);
DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
FileInputStream fis = new FileInputStream("test.txt")) {
File file = new File("test.txt");
dos.writeUTF(file.getName());
dos.writeLong(file.length());
byte[] buffer = new byte[4096];
int read;
while ((read = fis.read(buffer)) != -1) {
dos.write(buffer, 0, read);
}
System.out.println("文件发送完成");
} catch (IOException e) {
e.printStackTrace();
}
}
}
Socket选项
import java.net.Socket;
public class SocketOptionsDemo {
public static void main(String[] args) throws Exception {
Socket socket = new Socket();
socket.setTcpNoDelay(true);
socket.setSoTimeout(30000);
socket.setKeepAlive(true);
socket.setSendBufferSize(1024 * 1024);
socket.setReceiveBufferSize(1024 * 1024);
socket.setSoLinger(true, 30);
System.out.println("TCP No Delay: " + socket.getTcpNoDelay());
System.out.println("SO Timeout: " + socket.getSoTimeout());
System.out.println("Keep Alive: " + socket.getKeepAlive());
System.out.println("发送缓冲区: " + socket.getSendBufferSize());
System.out.println("接收缓冲区: " + socket.getReceiveBufferSize());
socket.close();
}
}
NIO Socket
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
public class NioSocketDemo {
public static void main(String[] args) throws IOException {
ServerSocketChannel serverChannel = ServerSocketChannel.open();
serverChannel.bind(new InetSocketAddress(8080));
serverChannel.configureBlocking(false);
System.out.println("NIO服务器启动...");
while (true) {
SocketChannel clientChannel = serverChannel.accept();
if (clientChannel != null) {
clientChannel.configureBlocking(false);
ByteBuffer buffer = ByteBuffer.allocate(1024);
int bytesRead = clientChannel.read(buffer);
if (bytesRead > 0) {
buffer.flip();
byte[] data = new byte[buffer.remaining()];
buffer.get(data);
System.out.println("收到: " + new String(data));
clientChannel.write(ByteBuffer.wrap("Echo".getBytes()));
}
clientChannel.close();
}
}
}
}
Socket最佳实践
- 使用try-with-resources自动关闭Socket
- 设置合理的超时时间
- 使用多线程处理多个客户端
- 考虑使用NIO提高性能
- 注意异常处理和资源释放
总结
Socket编程是Java网络编程的核心。掌握TCP/UDP Socket的使用,能帮助你构建各种网络应用。