2022 字
约 6 分钟
9
Java网络编程
无标签

第64章 Java网络编程

面包屑导航 章节头部 学习目标

学习目标

  • 理解网络编程的基本概念和原理
  • 掌握Socket编程的基础知识和使用方法
  • 学会TCP和UDP协议的区别和应用场景
  • 实现客户端和服务器端的通信程序
  • 了解网络编程的最佳实践和常见问题
  • 掌握多线程网络编程技术

网络编程基础

网络编程基础概念

网络编程是指编写能够在网络上进行数据通信的程序。Java提供了强大的网络编程API,使得开发网络应用变得相对简单。网络编程的核心是Socket(套接字),它是网络通信的端点。

Socket概念

// Socket是网络通信的端点
// 包含IP地址和端口号
// 用于建立网络连接
  • 网络通信的基础
  • 包含IP地址和端口号
  • 支持TCP和UDP协议
  • 提供双向数据传输

客户端/服务器模型

// 服务器:监听端口,等待连接
// 客户端:主动连接服务器
// 建立连接后进行数据交换
  • 服务器被动等待连接
  • 客户端主动发起连接
  • 支持多客户端连接
  • 可以双向通信

TCP编程

TCP Socket编程

TCP(传输控制协议)是一种可靠的、面向连接的协议。它保证数据的完整性和顺序,适用于对数据准确性要求较高的应用。

TCP服务器端编程

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

public class TCPServer {
    public static void main(String[] args) {
        try {
            // 创建服务器Socket,监听8080端口
            ServerSocket serverSocket = new ServerSocket(8080);
            System.out.println("服务器启动,监听端口8080...");
            
            while (true) {
                // 等待客户端连接
                Socket clientSocket = serverSocket.accept();
                System.out.println("客户端连接:" + clientSocket.getInetAddress());
                
                // 创建新线程处理客户端请求
                new Thread(new ClientHandler(clientSocket)).start();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

class ClientHandler implements Runnable {
    private 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);
            
            String inputLine;
            while ((inputLine = in.readLine()) != null) {
                System.out.println("收到消息:" + inputLine);
                out.println("服务器回复:" + inputLine);
            }
            
            clientSocket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

TCP客户端编程

import java.io.*;
import java.net.*;
import java.util.Scanner;

public class TCPClient {
    public static void main(String[] args) {
        try {
            // 连接到服务器
            Socket socket = new Socket("localhost", 8080);
            System.out.println("连接到服务器成功!");
            
            // 获取输入输出流
            PrintWriter out = new PrintWriter(
                socket.getOutputStream(), true);
            BufferedReader in = new BufferedReader(
                new InputStreamReader(socket.getInputStream()));
            
            Scanner scanner = new Scanner(System.in);
            String userInput;
            
            while (true) {
                System.out.print("请输入消息(输入'quit'退出):");
                userInput = scanner.nextLine();
                
                if ("quit".equalsIgnoreCase(userInput)) {
                    break;
                }
                
                // 发送消息到服务器
                out.println(userInput);
                
                // 接收服务器回复
                String response = in.readLine();
                System.out.println(response);
            }
            
            socket.close();
            scanner.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

UDP编程

UDP Socket编程

UDP(用户数据报协议)是一种无连接的协议,传输速度快但不保证数据的可靠性。适用于对实时性要求较高的应用,如视频流、游戏等。

UDP服务器端编程

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

public class UDPServer {
    public static void main(String[] args) {
        try {
            // 创建DatagramSocket,监听9999端口
            DatagramSocket socket = new DatagramSocket(9999);
            System.out.println("UDP服务器启动,监听端口9999...");
            
            byte[] buffer = new byte[1024];
            
            while (true) {
                // 创建数据包接收数据
                DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
                socket.receive(packet);
                
                // 获取客户端信息
                String message = new String(packet.getData(), 0, packet.getLength());
                InetAddress clientAddress = packet.getAddress();
                int clientPort = packet.getPort();
                
                System.out.println("收到来自 " + clientAddress + ":" + clientPort + " 的消息:" + message);
                
                // 回复客户端
                String response = "服务器收到:" + message;
                byte[] responseData = response.getBytes();
                DatagramPacket responsePacket = new DatagramPacket(
                    responseData, responseData.length, clientAddress, clientPort);
                socket.send(responsePacket);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

UDP客户端编程

import java.net.*;
import java.io.*;
import java.util.Scanner;

public class UDPClient {
    public static void main(String[] args) {
        try {
            DatagramSocket socket = new DatagramSocket();
            InetAddress serverAddress = InetAddress.getByName("localhost");
            int serverPort = 9999;
            
            Scanner scanner = new Scanner(System.in);
            
            while (true) {
                System.out.print("请输入消息(输入'quit'退出):");
                String message = scanner.nextLine();
                
                if ("quit".equalsIgnoreCase(message)) {
                    break;
                }
                
                // 发送数据到服务器
                byte[] data = message.getBytes();
                DatagramPacket packet = new DatagramPacket(
                    data, data.length, serverAddress, serverPort);
                socket.send(packet);
                
                // 接收服务器回复
                byte[] buffer = new byte[1024];
                DatagramPacket responsePacket = new DatagramPacket(buffer, buffer.length);
                socket.receive(responsePacket);
                
                String response = new String(responsePacket.getData(), 0, responsePacket.getLength());
                System.out.println(response);
            }
            
            socket.close();
            scanner.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

协议比较

TCP vs UDP 协议比较

特性 TCP UDP
连接性 面向连接 无连接
可靠性 可靠传输,保证数据完整性 不可靠传输,可能丢失数据
速度 相对较慢 快速
数据顺序 保证数据顺序 不保证数据顺序
头部开销 20字节 8字节
适用场景 文件传输、网页浏览、邮件 视频流、游戏、DNS查询

高级网络编程

高级网络编程技术

多线程服务器

import java.io.*;
import java.net.*;
import java.util.concurrent.*;

public class ThreadPoolServer {
    private static final int PORT = 8080;
    private static final int THREAD_POOL_SIZE = 10;
    
    public static void main(String[] args) {
        // 创建线程池
        ExecutorService executor = Executors.newFixedThreadPool(THREAD_POOL_SIZE);
        
        try {
            ServerSocket serverSocket = new ServerSocket(PORT);
            System.out.println("线程池服务器启动,监听端口" + PORT);
            
            while (true) {
                Socket clientSocket = serverSocket.accept();
                // 将客户端处理任务提交给线程池
                executor.submit(new ClientTask(clientSocket));
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            executor.shutdown();
        }
    }
}

class ClientTask implements Runnable {
    private Socket clientSocket;
    
    public ClientTask(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);
            
            String inputLine;
            while ((inputLine = in.readLine()) != null) {
                // 处理客户端请求
                String response = processRequest(inputLine);
                out.println(response);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                clientSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    
    private String processRequest(String request) {
        // 模拟业务处理
        return "处理结果:" + request.toUpperCase();
    }
}

异常处理和资源管理

public class SafeNetworkClient {
    public static void main(String[] args) {
        // 使用try-with-resources确保资源正确关闭
        try (Socket socket = new Socket("localhost", 8080);
             PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
             BufferedReader in = new BufferedReader(
                 new InputStreamReader(socket.getInputStream()))) {
            
            // 设置超时时间
            socket.setSoTimeout(5000); // 5秒超时
            
            out.println("Hello Server");
            String response = in.readLine();
            System.out.println("服务器回复:" + response);
            
        } catch (SocketTimeoutException e) {
            System.err.println("连接超时:" + e.getMessage());
        } catch (ConnectException e) {
            System.err.println("连接被拒绝:" + e.getMessage());
        } catch (IOException e) {
            System.err.println("网络错误:" + e.getMessage());
        }
    }
}

最佳实践

网络编程最佳实践

推荐做法

  • 使用try-with-resources管理资源
  • 设置合适的超时时间
  • 使用线程池处理并发连接
  • 正确处理网络异常
  • 使用缓冲流提高性能
  • 及时关闭网络连接

避免做法

  • 忘记关闭Socket连接
  • 不处理网络异常
  • 在主线程中进行阻塞操作
  • 不设置超时时间
  • 忽略线程安全问题
  • 不验证网络数据

实际应用示例

实际应用示例

简单聊天室应用结合TCP Socket和多线程技术,可以实现一个简单的聊天室应用,支持多用户同时在线聊天。

安全注意事项在实际应用中,需要考虑数据加密、身份验证、防止DOS攻击等安全问题。

性能优化建议

使用NIO(非阻塞I/O)可以进一步提高网络应用的性能和并发处理能力。
代码演示链接 💻 查看完整代码 - 在线IDE体验 章节总结

章节总结

  • 网络编程是现代应用开发的重要技能
  • Socket是网络通信的基础,包含IP地址和端口号
  • TCP协议可靠但相对较慢,适用于数据完整性要求高的场景
  • UDP协议快速但不可靠,适用于实时性要求高的场景
  • 多线程编程可以提高服务器的并发处理能力
  • 正确的异常处理和资源管理是网络编程的关键
  • 安全性和性能优化在实际应用中非常重要

导航链接 上一章:Lambda表达式 章节测试 下一章:日志和调试

Java网络编程
https://clxhxhhr.top/posts/2765/
作者
clxstart
发布于
2026-09-19
许可协议
CC BY-NC-SA 4.0
评论
0 条
还没有评论,先写一条吧。