跳转至

网络编程

📖 章节简介

本章将介绍Java的网络编程,包括Socket编程、HTTP客户端和服务器的基本使用。

Java网络编程能力地图

上图覆盖 TCP、UDP 与 HTTP 三类常见网络编程模式及定位。

🌐 Socket编程

1. Socket基础

Java
// Socket客户端
import java.io.*;
import java.net.*;

public class SocketClient {
    public static void main(String[] args) {
        String host = "localhost";
        int port = 8080;

        try (Socket socket = new Socket(host, port);
             PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
             BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()))) {

            // 发送消息
            out.println("Hello, Server!");

            // 接收响应
            String response = in.readLine();
            System.out.println("服务器响应: " + response);

        } catch (IOException e) {
            System.out.println("连接失败: " + e.getMessage());
        }
    }
}

// Socket服务器
import java.io.*;
import java.net.*;

public class SocketServer {
    public static void main(String[] args) {
        int port = 8080;

        try (ServerSocket serverSocket = new ServerSocket(port)) {
            System.out.println("服务器启动,监听端口: " + port);

            while (true) {
                try (Socket clientSocket = serverSocket.accept();
                     PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
                     BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()))) {

                    System.out.println("客户端连接: " + clientSocket.getInetAddress());

                    // 接收消息
                    String message = in.readLine();
                    System.out.println("客户端消息: " + message);

                    // 发送响应
                    out.println("Hello, Client!");

                } catch (IOException e) {
                    System.out.println("处理客户端失败: " + e.getMessage());
                }
            }
        } catch (IOException e) {
            System.out.println("服务器启动失败: " + e.getMessage());
        }
    }
}

2. UDP编程

Java
// UDP发送端
import java.net.*;

public class UDPSender {
    public static void main(String[] args) throws Exception {
        DatagramSocket socket = new DatagramSocket();

        String message = "Hello, UDP!";
        byte[] buffer = message.getBytes();

        InetAddress address = InetAddress.getByName("localhost");
        int port = 9876;

        DatagramPacket packet = new DatagramPacket(buffer, buffer.length, address, port);
        socket.send(packet);

        System.out.println("消息已发送");
        socket.close();
    }
}

// UDP接收端
import java.net.*;

public class UDPReceiver {
    public static void main(String[] args) throws Exception {
        DatagramSocket socket = new DatagramSocket(9876);

        byte[] buffer = new byte[1024];
        DatagramPacket packet = new DatagramPacket(buffer, buffer.length);

        System.out.println("等待接收消息...");
        socket.receive(packet);

        String message = new String(packet.getData(), 0, packet.getLength());
        System.out.println("收到消息: " + message);
        System.out.println("发送者: " + packet.getAddress());

        socket.close();
    }
}

🌍 HTTP客户端

1. HttpURLConnection

Java
// HTTP客户端
import java.io.*;
import java.net.*;

public class HttpClient {
    public static void main(String[] args) throws Exception {
        String urlString = "https://api.example.com/data";

        // 注意:new URL(String) 自 Java 20 起已弃用,使用 URI.create().toURL()
        URL url = URI.create(urlString).toURL();
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();

        // 设置请求方法
        connection.setRequestMethod("GET");

        // 设置请求头
        connection.setRequestProperty("Accept", "application/json");
        connection.setRequestProperty("User-Agent", "MyClient/1.0");

        // 设置超时
        connection.setConnectTimeout(5000);
        connection.setReadTimeout(5000);

        int responseCode = connection.getResponseCode();
        System.out.println("响应码: " + responseCode);

        if (responseCode == HttpURLConnection.HTTP_OK) {
            // 读取响应
            BufferedReader in = new BufferedReader(
                new InputStreamReader(connection.getInputStream()));

            String line;
            StringBuilder response = new StringBuilder();

            while ((line = in.readLine()) != null) {
                response.append(line);
            }

            in.close();
            System.out.println("响应内容: " + response.toString());
        } else {
            System.out.println("请求失败");
        }

        connection.disconnect();
    }
}

2. POST请求

Java
// POST请求
import java.io.*;
import java.net.*;

public class HttpPostClient {
    public static void main(String[] args) throws Exception {
        String urlString = "https://api.example.com/users";

        URL url = URI.create(urlString).toURL();
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();

        // 设置请求方法
        connection.setRequestMethod("POST");
        connection.setRequestProperty("Content-Type", "application/json");
        connection.setRequestProperty("Accept", "application/json");

        // 启用输出
        connection.setDoOutput(true);

        // 发送请求体
        String jsonInputString = "{\"name\":\"张三\",\"age\":25}";
        try (OutputStream os = connection.getOutputStream()) {
            byte[] input = jsonInputString.getBytes("utf-8");
            os.write(input, 0, input.length);
        }

        int responseCode = connection.getResponseCode();
        System.out.println("响应码: " + responseCode);

        if (responseCode == HttpURLConnection.HTTP_OK || responseCode == HttpURLConnection.HTTP_CREATED) {
            // 读取响应
            BufferedReader in = new BufferedReader(
                new InputStreamReader(connection.getInputStream()));

            String line;
            StringBuilder response = new StringBuilder();

            while ((line = in.readLine()) != null) {
                response.append(line);
            }

            in.close();
            System.out.println("响应内容: " + response.toString());
        }

        connection.disconnect();
    }
}

💡 最佳实践

1. 异常处理

Java
// 网络编程异常处理
public class NetworkExceptionHandling {
    // ✅ 好的做法:处理所有可能的异常
    public void connectToServer(String host, int port) {
        try {
            Socket socket = new Socket(host, port);
            // 处理连接
        } catch (UnknownHostException e) {
            System.out.println("未知主机: " + e.getMessage());
        } catch (ConnectException e) {
            System.out.println("连接被拒绝: " + e.getMessage());
        } catch (SocketTimeoutException e) {
            System.out.println("连接超时: " + e.getMessage());
        } catch (IOException e) {
            System.out.println("IO异常: " + e.getMessage());
        }
    }

    // ❌ 不好的做法:只捕获IOException
    public void connectToServerUnsafe(String host, int port) {
        try {
            Socket socket = new Socket(host, port);
            // 处理连接
        } catch (IOException e) {
            System.out.println("连接失败");  // 信息不明确
        }
    }
}

2. 资源管理

Java
import java.io.*;
import java.net.*;

// 网络资源管理
public class NetworkResourceManagement {
    // ✅ 好的做法:使用try-with-resources
    // 注意:new URL(String) 自 Java 20 起已弃用,推荐使用 URI.create(url).toURL()
    public void sendRequest1(String url) {
        try (BufferedReader in = new BufferedReader(
                new InputStreamReader(URI.create(url).toURL().openStream()))) {

            String line;
            while ((line = in.readLine()) != null) {
                System.out.println(line);
            }
        } catch (IOException e) {
            System.out.println("请求失败");
        }
    }

    // ❌ 不好的做法:手动关闭资源
    public void sendRequest2(String url) {
        BufferedReader in = null;
        try {
            in = new BufferedReader(
                new InputStreamReader(URI.create(url).toURL().openStream()));

            String line;
            while ((line = in.readLine()) != null) {
                System.out.println(line);
            }
        } catch (IOException e) {
            System.out.println("请求失败");
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    System.out.println("关闭失败");
                }
            }
        }
    }
}

📝 练习题

基础题

  1. 什么是Socket?
  2. TCP和UDP有什么区别?
  3. 如何发送HTTP请求?

进阶题

  1. 实现一个简单的聊天程序。
  2. 创建一个HTTP服务器。
  3. 使用线程处理多个客户端。

实践题

  1. 创建一个文件传输工具。
  2. 实现一个简单的Web爬虫。
  3. 构建一个在线投票系统。

📚 推荐阅读

🔗 下一章

实战项目 - 通过一个完整的学生管理系统项目综合运用所学知识。