悠悠楠杉
Java网络编程Socket通信完整实战教程:从入门到精通
一、Socket通信的本质
Socket是应用层与TCP/IP协议族通信的中间抽象层,就像两个城市之间的电话线路。在Java中,主要通过java.net
包实现,其核心思想可以概括为:
- 服务端:创建ServerSocket监听端口
- 客户端:创建Socket连接指定IP和端口
- 双向通道:建立成功后通过I/O流传输数据
java
// 最简服务端示例
ServerSocket server = new ServerSocket(8080);
Socket client = server.accept(); // 阻塞等待连接
二、TCP通信完整实战案例
2.1 基础通信模型
java
// 服务端代码
public class SimpleServer {
public static void main(String[] args) throws IOException {
try(ServerSocket server = new ServerSocket(9000)){
System.out.println("服务端启动...");
Socket socket = server.accept();
BufferedReader in = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
String msg = in.readLine();
System.out.println("收到客户端消息:" + msg);
}
}
}
// 客户端代码
public class SimpleClient {
public static void main(String[] args) throws IOException {
try(Socket socket = new Socket("localhost", 9000)){
PrintWriter out = new PrintWriter(
socket.getOutputStream(), true);
out.println("Hello Server!");
}
}
}
关键点说明:
- try-with-resources
自动关闭资源
- 输出流需要flush()
或设置autoFlush
- 默认采用阻塞式同步通信
2.2 多线程版本改进
基础版只能处理单个连接,实际需要多线程支持:
java
// 服务端线程池改造
ExecutorService pool = Executors.newCachedThreadPool();
while(true){
Socket client = server.accept();
pool.execute(() -> {
// 处理客户端请求
});
}
三、NIO非阻塞编程进阶
当并发量超过1000时,传统BIO模型会遇到性能瓶颈,这时需要NIO解决方案:
java
// NIO服务端示例
Selector selector = Selector.open();
ServerSocketChannel serverChannel = ServerSocketChannel.open();
serverChannel.bind(new InetSocketAddress(8080));
serverChannel.configureBlocking(false);
serverChannel.register(selector, SelectionKey.OP_ACCEPT);
while(true){
selector.select(); // 就绪事件检测
Iterator
while(iter.hasNext()){
SelectionKey key = iter.next();
if(key.isAcceptable()){
// 处理新连接
}
if(key.isReadable()){
// 处理读事件
}
iter.remove();
}
}
NIO的核心优势:
1. 单线程处理多连接(IO多路复用)
2. 基于事件驱动模型
3. 零拷贝技术提升性能
四、常见问题解决方案
粘包问题处理
- 固定长度协议
- 特殊分隔符(如
\n
) - 自定义协议头(长度+内容)
心跳机制实现
java // 心跳检测线程 socket.setSoTimeout(30000); // 30秒超时 while(true){ out.write("HEARTBEAT\n"); out.flush(); Thread.sleep(5000); }
传输对象数据
java // 使用ObjectOutputStream ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream()); oos.writeObject(new User("张三", 25));
五、性能优化建议
- 使用线程池控制资源
- 重要连接启用TCP KeepAlive
- 高并发场景考虑Netty框架
- Linux系统调优(文件描述符限制等)
总结:Socket编程是Java网络通信的基石,从基础的BIO到高效的NIO,开发者需要根据业务场景选择合适的模型。建议先从TCP协议入手理解通信本质,再逐步扩展到UDP和非阻塞编程领域。