亿迅智能制造网
工业4.0先进制造技术信息网站!
首页 | 制造技术 | 制造设备 | 工业物联网 | 工业材料 | 设备保养维修 | 工业编程 |
home  MfgRobots >> 亿迅智能制造网 >  >> Industrial programming >> java

Java 网络编程实战:Socket、ServerSocket 与 TCP/UDP 通信

Java java.net 包提供底层网络通信支持,核心协议:TCP(面向连接、可靠、流式)和 UDP(无连接、数据报、不可靠但低延迟)。

TCP Socket 编程模型

服务端流程

  1. ServerSocket server = new ServerSocket(port); 绑定端口监听
  2. Socket client = server.accept(); 阻塞等待客户端连接
  3. 通过 client.getInputStream()/getOutputStream() 通信
  4. 处理完关闭 client.close(),循环 accept 下一个

客户端流程

  1. Socket socket = new Socket(host, port); 连接服务端
  2. 获取流进行读写
  3. socket.close() 断开

完整 Echo 服务端


public class EchoServer {
    public static void main(String[] args) throws IOException {
        try (ServerSocket server = new ServerSocket(8888)) {
            System.out.println("服务端启动,监听 8888...");
            while (true) {
                try (Socket client = server.accept();
                     BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream(), StandardCharsets.UTF_8));
                     PrintWriter out = new PrintWriter(new OutputStreamWriter(client.getOutputStream(), StandardCharsets.UTF_8), true)) {
                    
                    String line;
                    while ((line = in.readLine()) != null) {
                        System.out.println("收到: " + line);
                        out.println("Echo: " + line); // autoFlush=true
                        if ("bye".equalsIgnoreCase(line)) break;
                    }
                } catch (IOException e) {
                    System.err.println("客户端异常: " + e.getMessage());
                }
            }
        }
    }
}

对应客户端


public class EchoClient {
    public static void main(String[] args) throws IOException {
        try (Socket socket = new Socket("localhost", 8888);
             BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream(), StandardCharsets.UTF_8));
             PrintWriter out = new PrintWriter(new OutputStreamWriter(socket.getOutputStream(), StandardCharsets.UTF_8), true);
             BufferedReader console = new BufferedReader(new InputStreamReader(System.in))) {
            
            String input;
            while ((input = console.readLine()) != null) {
                out.println(input);
                System.out.println("服务端回复: " + in.readLine());
                if ("bye".equalsIgnoreCase(input)) break;
            }
        }
    }
}

核心类 API 速查

ServerSocket

方法说明
new ServerSocket(int port)绑定端口,回log默认 50
new ServerSocket(port, backlog)指定等待队列长度
accept()阻塞等待连接,返回新 Socket
setSoTimeout(ms)设置 accept 超时,避免永久阻塞
bind(SocketAddress, backlog)无参构造后绑定

Socket

方法说明
new Socket(host, port)连接指定主机端口
connect(SocketAddress, timeout)带超时连接
getInputStream()/getOutputStream()获取字节流
setSoTimeout(ms)读操作超时
setTcpNoDelay(true)禁用 Nagle 算法,降低延迟
close()关闭连接(发送 FIN)

InetAddress


InetAddress local = InetAddress.getLocalHost(); // 本机地址
InetAddress google = InetAddress.getByName("www.google.com"); // DNS 解析
System.out.println(google.getHostAddress()); // IP 字符串

UDP 编程

基于 DatagramSocket 和 DatagramPacket,无连接、面向数据报。

UDP 服务端


try (DatagramSocket server = new DatagramSocket(9999)) {
    byte[] buf = new byte[1024];
    DatagramPacket packet = new DatagramPacket(buf, buf.length);
    while (true) {
        server.receive(packet); // 阻塞接收
        String msg = new String(packet.getData(), 0, packet.getLength(), StandardCharsets.UTF_8);
        System.out.println("来自 " + packet.getAddress() + ":" + packet.getPort() + " -> " + msg);
        
        // 回复
        byte[] reply = ("ACK: " + msg).getBytes(StandardCharsets.UTF_8);
        DatagramPacket replyPacket = new DatagramPacket(reply, reply.length, packet.getAddress(), packet.getPort());
        server.send(replyPacket);
    }
}

UDP 客户端


try (DatagramSocket client = new DatagramSocket()) {
    InetAddress serverAddr = InetAddress.getByName("localhost");
    String msg = "Hello UDP";
    byte[] buf = msg.getBytes(StandardCharsets.UTF_8);
    DatagramPacket packet = new DatagramPacket(buf, buf.length, serverAddr, 9999);
    client.send(packet);
    
    // 接收回复
    byte[] replyBuf = new byte[1024];
    DatagramPacket reply = new DatagramPacket(replyBuf, replyBuf.length);
    client.receive(reply);
    System.out.println("服务端回复: " + new String(reply.getData(), 0, reply.getLength(), StandardCharsets.UTF_8));
}

TCP vs UDP 选型

维度TCPUDP
连接三次握手建立连接无连接
可靠性保证有序、不丢、不重不保证,可能丢包/乱序/重复
流量控制滑动窗口无
开销头部 20+ 字节、状态维护头部 8 字节、无状态
适用HTTP、数据库、文件传输、IM直播、游戏、DNS、SNMP、实时音视频

高并发服务端架构演进

  1. 单线程阻塞:一次处理一个,吞吐极低
  2. 多线程/线程池:每连接一线程,C10K 问题(线程开销大)
  3. NIO 非阻塞:Selector + ServerSocketChannel,单线程管理多连接
  4. Netty 框架:生产级 NIO 框架,解决粘包/半包、内存管理、编解码
  5. 虚拟线程:Java 21+ Thread.ofVirtual(),轻量级线程,阻塞式写法达成高并发

最佳实践

java

  1. 精通 Java 运算符:类型、语法与实战示例
  2. Java 注释:类型、用法与最佳实践
  3. 精通 Java if…else:控制流全解析
  4. 精通 Java 增强 for 循环:语法、示例与最佳实践
  5. 精通 Java 字符串:创建、方法与最佳实践
  6. 精通 Java 接口:概念、实现与最佳实践
  7. 精通 Java 匿名内部类:定义、语法与实战示例
  8. 精通 Java Try-With-Resources:自动资源管理详解
  9. Java 注解详解:类型、放置位置与实战示例
  10. Java 断言实战指南:尽早发现 Bug 与保障代码可靠性
  11. 深入理解 Java Vector:用法、特性及与 ArrayList 的对比
  12. Java 网络编程实战:Socket、ServerSocket 与 TCP/UDP 通信