首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【关于Java的网络编程】

【关于Java的网络编程】

作者头像
艾伦耶格尔
发布2025-08-28 15:46:09
发布2025-08-28 15:46:09
12400
代码可运行
举报
文章被收录于专栏:Java基础Java基础
运行总次数:0
代码可运行

👉 你在浏览器输入 www.taobao.com,页面是怎么“蹦”出来的? 👉 你用微信发一条消息,对方是怎么“秒收”的? 👉 面试官问:“说说 Java 的网络编程?” 你脑子里闪过 SocketServerSocket,但串不起来,说不完整……


一、网络编程是啥?—— 让程序“打电话”

想象一下你给朋友打电话:

  1. 你拨号(知道对方号码)
  2. 对方手机响,接听
  3. 你们开始说话(数据传输)
  4. 说完挂电话

在 Java 世界里,网络编程就是让两个程序像打电话一样通信

而 Java 提供了一套标准 API,让我们可以用代码实现这个过程。

网络编程 = 通过代码,让不同机器上的程序互相传递数据


二、核心概念:IP、端口、协议

1. IP 地址:电脑的“手机号”

就像每个人有手机号,每台联网的设备都有一个 IP 地址,比如 192.168.1.100127.0.0.1(本机)。

2. 端口(Port):应用的“分机号”

一台电脑可能运行多个网络程序(微信、浏览器、游戏)。 IP 地址只能定位到电脑,端口用来定位具体的应用

💡 端口就像公司总机的“分机号”: 总机是 IP,分机是 Port。

常见端口:

  • 80:HTTP(网页)
  • 443:HTTPS
  • 3306:MySQL
  • 6379:Redis
  • 8080:常用作 Web 服务器测试端口
3. 协议:通话的“语言规则”

通信双方必须遵守相同的“语言规则”,否则鸡同鸭讲。

Java 网络编程最常用的是:

  • TCP:可靠、有序、面向连接(像打电话)
  • UDP:不可靠、速度快、无连接(像发短信)

✅ 我们重点讲 TCP,因为它是 Java 网络编程的基石。


三、TCP 通信模型:客户端 & 服务器

TCP 通信就像“客服热线”:

代码语言:javascript
代码运行次数:0
运行
复制
[客户端] --- 拨号 ---> [服务器]
   |                      |
   |  发送请求              | 接收请求
   | ---------------------> |
   |                      |
   |  等待响应              | 处理并返回
   | <--------------------- |
   |                      |
   |  接收响应              |
   |                      |
  • 客户端(Client):主动发起连接的一方(如浏览器)
  • 服务器(Server):被动等待连接,处理请求(如 Tomcat)

四、Java 实现 TCP 通信:Socket 编程

Java 用两个核心类实现 TCP 通信:

角色

Java 类

作用

客户端

Socket

发起连接,收发数据

服务器

ServerSocket

监听端口,接收连接


🎯 场景1:写一个简单的“回声服务器”(ECHO Server)

功能:客户端发啥,服务器原样返回。

1. 服务器端代码
代码语言:javascript
代码运行次数:0
运行
复制
public class EchoServer {
    public static void main(String[] args) throws IOException {
        // 1. 创建服务器,监听 8888 端口
        ServerSocket serverSocket = new ServerSocket(8888);
        System.out.println("服务器启动,等待连接...");

        while (true) {
            // 2. 接收客户端连接(阻塞)
            Socket clientSocket = serverSocket.accept();
            System.out.println("客户端已连接:" + clientSocket.getInetAddress());

            // 3. 获取输入输出流
            BufferedReader in = new BufferedReader(
                new InputStreamReader(clientSocket.getInputStream())
            );
            PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);

            // 4. 读取客户端消息,原样返回
            String msg;
            while ((msg = in.readLine()) != null) {
                System.out.println("收到:" + msg);
                out.println("ECHO: " + msg); // 原样返回
            }

            // 5. 关闭资源
            clientSocket.close();
        }
    }
}
2. 客户端代码
代码语言:javascript
代码运行次数:0
运行
复制
public class EchoClient {
    public static void main(String[] args) throws IOException {
        // 1. 连接服务器(IP: 127.0.0.1,端口: 8888)
        Socket socket = new Socket("127.0.0.1", 8888);

        // 2. 获取输入输出流
        PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
        BufferedReader in = new BufferedReader(
            new InputStreamReader(socket.getInputStream())
        );
        BufferedReader console = new BufferedReader(
            new InputStreamReader(System.in)
        );

        // 3. 发送消息,接收响应
        String input;
        while ((input = console.readLine()) != null) {
            out.println(input); // 发送
            String response = in.readLine(); // 接收
            System.out.println("服务器返回:" + response);
        }

        socket.close();
    }
}
✅ 运行效果:
代码语言:javascript
代码运行次数:0
运行
复制
// 客户端输入
Hello
服务器返回:ECHO: Hello

Java Network
服务器返回:ECHO: Java Network

🎯 场景2:支持多客户端(用线程池)

上面的服务器只能服务一个客户端,第二个连不上。

问题accept()readLine() 都是阻塞的!

解决方案:每来一个客户端,就开一个线程处理。

代码语言:javascript
代码运行次数:0
运行
复制
// 在服务器端,修改处理逻辑
while (true) {
    Socket clientSocket = serverSocket.accept();
    System.out.println("新客户端:" + clientSocket.getInetAddress());

    // 开启新线程处理
    new Thread(() -> {
        try (BufferedReader in = new BufferedReader(
                new InputStreamReader(clientSocket.getInputStream()));
             PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true)) {

            String msg;
            while ((msg = in.readLine()) != null) {
                System.out.println("收到:" + msg);
                out.println("ECHO: " + msg);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                clientSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }).start();
}

💡 实际项目中,会用 线程池 替代 new Thread(),避免创建过多线程。


五、UDP 编程:发短信式通信

UDP 不建立连接,直接发数据包,速度快但不保证送达。

核心类:

  • DatagramSocket:发送/接收数据包
  • DatagramPacket:数据包(含数据、IP、端口)
🎯 场景:客户端发消息,服务器接收并打印
服务器端(接收)
代码语言:javascript
代码运行次数:0
运行
复制
public class UDPServer {
    public static void main(String[] args) throws IOException {
        DatagramSocket socket = new DatagramSocket(9999);
        byte[] buffer = new byte[1024];

        while (true) {
            DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
            socket.receive(packet); // 阻塞接收

            String msg = new String(packet.getData(), 0, packet.getLength());
            System.out.println("收到:" + msg + " 来自 " + packet.getAddress() + ":" + packet.getPort());
        }
    }
}
客户端(发送)
代码语言:javascript
代码运行次数:0
运行
复制
public class UDPClient {
    public static void main(String[] args) throws IOException {
        DatagramSocket socket = new DatagramSocket();
        String msg = "Hello UDP!";
        byte[] data = msg.getBytes();

        InetAddress serverAddr = InetAddress.getByName("127.0.0.1");
        DatagramPacket packet = new DatagramPacket(data, data.length, serverAddr, 9999);

        socket.send(packet);
        socket.close();
    }
}

✅ UDP 适用于:视频直播、在线游戏、DNS 查询等对速度要求高、能容忍少量丢包的场景。


六、高频问题 & 高分回答

Q1: 说说 TCP 和 UDP 的区别?

区别点

TCP

UDP

是否连接

面向连接(三次握手)

无连接

可靠性

可靠,保证送达、有序

不可靠,可能丢包、乱序

速度

较慢(建立连接、确认机制)

快(直接发)

用途

文件传输、网页、邮件

视频、游戏、广播

实现类

Socket / ServerSocket

DatagramSocket / DatagramPacket

💬 高分回答: “TCP 像打电话,必须接通才能说话,保证每句话都听到;UDP 像发短信,发了就不管了,但速度快。我们项目中 HTTP 用 TCP,实时推送用 WebSocket(底层也是 TCP),只有对延迟极度敏感的场景才考虑 UDP。”


Q2: 什么是 Socket?它包含哪些信息?

Socket 是网络通信的“端点”,它封装了:

  • 远程 IP 地址
  • 远程端口号
  • 本地 IP 和端口
  • 输入/输出流

它是应用层与传输层之间的接口,Java 通过 Socket 类提供了统一的编程方式。


Q3: 为什么服务器要用多线程?不用会怎样?

: 因为 accept()read() 都是阻塞的。如果不开启新线程,一个客户端连接后,服务器就卡在读数据上,其他客户端无法连接。 用多线程(或线程池)可以让每个客户端独立处理,实现并发服务。 我们项目中用的是线程池,避免频繁创建线程导致资源耗尽。


Q4: BIO 和 NIO 有什么区别?

  • BIO(Blocking I/O):传统方式,每个连接一个线程,资源消耗大,不适合高并发。
  • NIO(Non-blocking I/O):基于事件驱动,用 Selector 监听多个通道,一个线程可处理多个连接,适合高并发。 我们项目中普通文件服务用 BIO,网关和消息中间件用 Netty(基于 NIO),支撑了上万并发。

✅ 总结:一张表搞懂 Java 网络编程

问题

答案

核心类

Socket(客户端)、ServerSocket(服务器)

TCP 特点

面向连接、可靠、有序、慢

UDP 特点

无连接、不可靠、快、可能丢包

阻塞问题

用多线程或线程池解决

实际应用

HTTP、RPC、聊天室、文件传输

怎么说

“我写过 TCP 回声服务器,支持多客户端,理解阻塞与线程模型”


🔚 最后一句话

网络编程不是“古董”,而是“一切分布式系统的基石”。 从 Spring Boot 到 Dubbo,从 Redis 到 Kafka,底层都是 Socket 通信。 掌握它,你才能真正理解“一个请求是怎么跨过网络,被另一台机器处理的”。

希望这篇能帮你彻底搞懂 Java 网络编程!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-08-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、网络编程是啥?—— 让程序“打电话”
  • 二、核心概念:IP、端口、协议
    • 1. IP 地址:电脑的“手机号”
    • 2. 端口(Port):应用的“分机号”
    • 3. 协议:通话的“语言规则”
  • 三、TCP 通信模型:客户端 & 服务器
  • 四、Java 实现 TCP 通信:Socket 编程
    • 🎯 场景1:写一个简单的“回声服务器”(ECHO Server)
      • 1. 服务器端代码
      • 2. 客户端代码
      • ✅ 运行效果:
    • 🎯 场景2:支持多客户端(用线程池)
  • 五、UDP 编程:发短信式通信
    • 🎯 场景:客户端发消息,服务器接收并打印
      • 服务器端(接收)
      • 客户端(发送)
  • 六、高频问题 & 高分回答
    • Q1: 说说 TCP 和 UDP 的区别?
    • Q2: 什么是 Socket?它包含哪些信息?
    • Q3: 为什么服务器要用多线程?不用会怎样?
    • Q4: BIO 和 NIO 有什么区别?
  • ✅ 总结:一张表搞懂 Java 网络编程
  • 🔚 最后一句话
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档