news 2026/2/14 9:51:11

Java网络编程入门:从Socket到多线程服务器

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Java网络编程入门:从Socket到多线程服务器

在当今互联的世界中,网络编程已成为Java开发者必备的技能之一。无论是构建微服务架构、实现实时通信应用,还是开发分布式系统,网络编程都扮演着核心角色。本文将带你走进Java网络编程的世界,从基础概念到实际应用,一步步构建你的网络编程能力。

一、网络编程基础概念

1.1 TCP vs UDP

  • TCP:面向连接、可靠传输、数据顺序保证

  • UDP:无连接、快速、可能丢包

1.2 核心概念

  • IP地址:设备的网络标识

  • 端口号:应用程序的通信端点(0-65535)

  • Socket:网络通信的端点抽象

二、简单的TCP客户端/服务器示例

2.1 基础TCP服务器

import java.io.*; import java.net.*; public class SimpleTCPServer { public static void main(String[] args) { final int PORT = 8888; try (ServerSocket serverSocket = new ServerSocket(PORT)) { System.out.println("服务器启动,监听端口: " + PORT); while (true) { // 等待客户端连接 Socket clientSocket = serverSocket.accept(); System.out.println("客户端连接: " + clientSocket.getInetAddress()); // 处理客户端请求 handleClient(clientSocket); } } catch (IOException e) { e.printStackTrace(); } } private static void handleClient(Socket clientSocket) { try (BufferedReader in = new BufferedReader( new InputStreamReader(clientSocket.getInputStream())); PrintWriter out = new PrintWriter( clientSocket.getOutputStream(), true)) { String request; while ((request = in.readLine()) != null) { System.out.println("收到: " + request); out.println("服务器回复: " + request.toUpperCase()); } } catch (IOException e) { System.out.println("客户端断开连接"); } } }

2.2 基础TCP客户端

import java.io.*; import java.net.*; public class SimpleTCPClient { public static void main(String[] args) { final String SERVER_ADDRESS = "localhost"; final int PORT = 8888; try (Socket socket = new Socket(SERVER_ADDRESS, PORT); BufferedReader in = new BufferedReader( new InputStreamReader(socket.getInputStream())); PrintWriter out = new PrintWriter( socket.getOutputStream(), true); BufferedReader userInput = new BufferedReader( new InputStreamReader(System.in))) { System.out.println("已连接到服务器"); String userInputLine; while ((userInputLine = userInput.readLine()) != null) { out.println(userInputLine); System.out.println("服务器回复: " + in.readLine()); if ("exit".equalsIgnoreCase(userInputLine)) { break; } } } catch (UnknownHostException e) { System.err.println("未知主机: " + SERVER_ADDRESS); } catch (IOException e) { System.err.println("IO异常: " + e.getMessage()); } } }

三、多线程服务器实现

单线程服务器无法处理并发连接,让我们升级为多线程版本:

import java.io.*; import java.net.*; import java.util.concurrent.*; public class MultiThreadedServer { private static final int PORT = 8888; private static final ExecutorService threadPool = Executors.newCachedThreadPool(); public static void main(String[] args) { try (ServerSocket serverSocket = new ServerSocket(PORT)) { System.out.println("多线程服务器启动,端口: " + PORT); while (true) { Socket clientSocket = serverSocket.accept(); threadPool.execute(new ClientHandler(clientSocket)); } } catch (IOException e) { e.printStackTrace(); } finally { threadPool.shutdown(); } } static class ClientHandler implements Runnable { private final 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)) { out.println("欢迎连接到服务器!当前线程: " + Thread.currentThread().getName()); String inputLine; while ((inputLine = in.readLine()) != null) { if ("exit".equalsIgnoreCase(inputLine)) { out.println("再见!"); break; } out.println("回声: " + inputLine); } } catch (IOException e) { System.out.println("客户端异常断开"); } finally { try { clientSocket.close(); } catch (IOException e) { e.printStackTrace(); } } } } }

四、UDP编程示例

import java.net.*; import java.io.*; public class UDPExample { // UDP 服务器 static class UDPServer { public static void main(String[] args) throws IOException { DatagramSocket socket = new DatagramSocket(8888); byte[] buffer = new byte[1024]; System.out.println("UDP服务器启动..."); while (true) { DatagramPacket packet = new DatagramPacket(buffer, buffer.length); socket.receive(packet); String received = new String(packet.getData(), 0, packet.getLength()); System.out.println("收到: " + received); // 发送响应 String response = "UDP响应: " + received.toUpperCase(); byte[] responseData = response.getBytes(); DatagramPacket responsePacket = new DatagramPacket( responseData, responseData.length, packet.getAddress(), packet.getPort() ); socket.send(responsePacket); } } } // UDP 客户端 static class UDPClient { public static void main(String[] args) throws IOException { DatagramSocket socket = new DatagramSocket(); InetAddress address = InetAddress.getByName("localhost"); BufferedReader userInput = new BufferedReader( new InputStreamReader(System.in)); while (true) { System.out.print("输入消息: "); String message = userInput.readLine(); // 发送消息 byte[] sendData = message.getBytes(); DatagramPacket sendPacket = new DatagramPacket( sendData, sendData.length, address, 8888); socket.send(sendPacket); // 接收响应 byte[] receiveData = new byte[1024]; DatagramPacket receivePacket = new DatagramPacket( receiveData, receiveData.length); socket.receive(receivePacket); String response = new String(receivePacket.getData(), 0, receivePacket.getLength()); System.out.println("服务器响应: " + response); if ("exit".equalsIgnoreCase(message)) { break; } } socket.close(); } } }

五、实战:简单的聊天室服务器

import java.io.*; import java.net.*; import java.util.*; import java.util.concurrent.*; public class ChatRoomServer { private static final int PORT = 9999; private static final Set<ClientHandler> clients = ConcurrentHashMap.newKeySet(); public static void main(String[] args) { ExecutorService pool = Executors.newCachedThreadPool(); try (ServerSocket serverSocket = new ServerSocket(PORT)) { System.out.println("聊天室服务器启动,端口: " + PORT); while (true) { Socket clientSocket = serverSocket.accept(); ClientHandler client = new ClientHandler(clientSocket); clients.add(client); pool.execute(client); } } catch (IOException e) { e.printStackTrace(); } } static class ClientHandler implements Runnable { private Socket socket; private PrintWriter out; private String clientName; public ClientHandler(Socket socket) { this.socket = socket; } @Override public void run() { try { out = new PrintWriter(socket.getOutputStream(), true); BufferedReader in = new BufferedReader( new InputStreamReader(socket.getInputStream())); // 获取客户端名称 out.println("请输入你的名字:"); clientName = in.readLine(); broadcast(clientName + " 加入了聊天室"); String message; while ((message = in.readLine()) != null) { if ("/exit".equalsIgnoreCase(message)) { break; } broadcast(clientName + ": " + message); } } catch (IOException e) { System.out.println(clientName + " 异常断开"); } finally { try { socket.close(); } catch (IOException e) { e.printStackTrace(); } clients.remove(this); broadcast(clientName + " 离开了聊天室"); } } private void broadcast(String message) { System.out.println(message); for (ClientHandler client : clients) { if (client != this) { client.out.println(message); } } } } }

六、最佳实践与注意事项

6.1 资源管理

  • 始终使用try-with-resources确保资源关闭

  • 注意处理各种IO异常

6.2 性能考虑

  • 使用线程池管理连接

  • 考虑使用NIO处理大量并发连接

  • 合理设置缓冲区大小

6.3 安全性

  • 验证输入数据

  • 防止缓冲区溢出

  • 使用SSL/TLS进行加密通信

七、下一步学习方向

  1. Java NIO:学习非阻塞IO,处理高并发场景

  2. Netty框架:企业级网络应用框架

  3. HTTP客户端:Java 11+的HttpClient API

  4. WebSocket:实现实时双向通信

  5. RPC框架:如gRPC、Dubbo等

结语

Java网络编程是一个既基础又强大的技能。从简单的Socket编程开始,逐步深入到多线程、NIO,再到使用成熟的网络框架,这个过程充满挑战但也极具价值。掌握网络编程不仅能让你更好地理解网络通信的本质,还能为构建分布式系统打下坚实基础。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/14 3:11:59

Content-Type自动化:节省开发者80%配置时间

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 开发一个效率对比工具&#xff0c;左侧展示传统手动配置Content-Type的方式&#xff0c;右侧展示使用AI自动检测和设置的方式。统计并可视化两种方式的时间消耗和准确率差异。要求…

作者头像 李华
网站建设 2026/2/9 23:41:19

奇异值分解实战:从图像压缩到数据去噪

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 在快马平台生成一个图像压缩工具&#xff0c;利用SVD对输入的图片进行分解和重构。用户可以调整保留的奇异值数量&#xff0c;实时预览压缩效果和文件大小变化。输出包括压缩前后的…

作者头像 李华
网站建设 2026/2/12 14:56:57

零基础教程:5分钟搭建个人网速测试页面

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 创建一个极简网速测试页面&#xff0c;功能&#xff1a;1. 单按钮启动测试 2. 显示基本下载/上传速度 3. 可视化进度条 4. 移动端适配 5. 可自定义外观主题。使用纯HTML/CSS/JavaS…

作者头像 李华
网站建设 2026/2/9 6:58:19

企业级红队演练:COBALT STRIKE实战案例解析

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 创建一个COBALT STRIKE实战演练模拟环境&#xff0c;包含&#xff1a;1. 典型企业网络拓扑(AD域、Web服务器、数据库等) 2. 预设漏洞点 3. 完整攻击剧本 4. 防御检测点。要求提供逐…

作者头像 李华
网站建设 2026/2/4 1:52:00

Paraformer-large识别失败?Gradio可视化部署问题解决全攻略

Paraformer-large识别失败&#xff1f;Gradio可视化部署问题解决全攻略 你是不是也遇到过这样的情况&#xff1a;好不容易部署好了Paraformer-large语音识别模型&#xff0c;结果上传音频后点击“开始转写”&#xff0c;界面卡住不动、返回空白&#xff0c;甚至直接报错“识别…

作者头像 李华
网站建设 2026/2/14 8:32:09

用PINN快速验证物理假设:10分钟原型开发指南

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 创建一个PINN快速原型开发工具包&#xff0c;功能包括&#xff1a;1) 物理方程模板库&#xff1b;2) 一键生成基础网络架构&#xff1b;3) 自动训练流程&#xff1b;4) 实时结果可…

作者头像 李华