本文最后更新于 2025-10-30,文章内容可能已经过时。

Java网络编程是Java语言中用于实现计算机网络通信的技术,基于Java的网络API(主要在java.net包中)提供了一系列类和接口,使开发者能够轻松地实现网络应用程序。

网络通信基础

1. 网络通信要素

  • IP地址和域名

    • IP地址:网络中设备的唯一标识(IPv4:32位,如192.168.1.1;IPv6:128位)
    • 域名:便于记忆的地址(如www.google.com),通过DNS解析为IP地址
  • 端口号

    • 用两个字节表示(0~65535)
    • 公认端口(0~1023):HTTP(80)、FTP(21)、Telnet(23)
    • 注册端口(1024~49151):Tomcat(8080)、MySQL(3306)
    • 动态/私有端口(49152~65535)
  • 网络通信协议

    • TCP(传输控制协议):面向连接、可靠、基于字节流
    • UDP(用户数据报协议):无连接、快速、不可靠
    • HTTP/HTTPS:应用层协议,用于Web通信

2. 网络模型

  • OSI七层模型:物理层、数据链路层、网络层、传输层、会话层、表示层、应用层
  • TCP/IP四层模型:网络接口层、网际层、传输层、应用层

Java网络编程核心类

1. InetAddress类

用于处理IP地址和域名解析

InetAddress localHost = InetAddress.getLocalHost(); // 获取本地主机信息
InetAddress googleHost = InetAddress.getByName("www.google.com"); // 通过主机名获取IP

2. Socket类

客户端使用,建立与服务器的连接

Socket socket = new Socket("localhost", 8989); // 连接到服务器
OutputStream outputStream = socket.getOutputStream(); // 获取输出流
InputStream inputStream = socket.getInputStream(); // 获取输入流

3. ServerSocket类

服务器端使用,监听客户端连接请求

ServerSocket serverSocket = new ServerSocket(8989); // 监听端口
Socket clientSocket = serverSocket.accept(); // 接受客户端连接

4. URL类

处理统一资源定位符

URL url = new URL("http://www.example.com");
InputStream inputStream = url.openStream(); // 打开连接获取输入流

TCP编程示例

服务器端

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

public class TcpServer {
    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = new ServerSocket(8989);
        System.out.println("服务器已启动,等待连接...");
        
        while (true) {
            Socket clientSocket = serverSocket.accept();
            System.out.println("客户端已连接");
            
            new Thread(new ClientHandler(clientSocket)).start();
        }
    }
    
    static class ClientHandler implements Runnable {
        private Socket socket;
        
        public ClientHandler(Socket socket) {
            this.socket = socket;
        }
        
        public void run() {
            try (InputStream input = socket.getInputStream();
                 OutputStream output = socket.getOutputStream()) {
                
                byte[] buffer = new byte[1024];
                int bytesRead;
                
                while ((bytesRead = input.read(buffer)) != -1) {
                    String message = new String(buffer, 0, bytesRead);
                    System.out.println("收到客户端消息: " + message);
                    
                    output.write(("服务器收到: " + message).getBytes());
                    output.flush();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

客户端

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

public class TcpClient {
    public static void main(String[] args) throws IOException {
        Socket socket = new Socket("localhost", 8989);
        
        try (OutputStream output = socket.getOutputStream();
             InputStream input = socket.getInputStream()) {
            
            output.write("Hello, Server!".getBytes());
            output.flush();
            
            byte[] buffer = new byte[1024];
            int bytesRead = input.read(buffer);
            String response = new String(buffer, 0, bytesRead);
            System.out.println("服务器响应: " + response);
        }
    }
}

UDP编程示例

服务器端

import java.net.*;

public class UdpServer {
    public static void main(String[] args) throws Exception {
        DatagramSocket serverSocket = new DatagramSocket(9090);
        
        byte[] receiveBuffer = new byte[1024];
        DatagramPacket receivePacket = new DatagramPacket(receiveBuffer, receiveBuffer.length);
        
        while (true) {
            serverSocket.receive(receivePacket);
            
            String message = new String(receivePacket.getData(), 0, receivePacket.getLength());
            System.out.println("收到客户端消息: " + message);
            
            String response = "服务器收到: " + message;
            byte[] responseBytes = response.getBytes();
            DatagramPacket responsePacket = new DatagramPacket(responseBytes, responseBytes.length, 
                    receivePacket.getAddress(), receivePacket.getPort());
            serverSocket.send(responsePacket);
        }
    }
}

客户端

import java.net.*;

public class UdpClient {
    public static void main(String[] args) throws Exception {
        DatagramSocket clientSocket = new DatagramSocket();
        
        String message = "Hello, UDP Server!";
        byte[] messageBytes = message.getBytes();
        
        InetAddress serverAddress = InetAddress.getByName("localhost");
        DatagramPacket sendPacket = new DatagramPacket(messageBytes, messageBytes.length, 
                serverAddress, 9090);
        clientSocket.send(sendPacket);
        
        byte[] receiveBuffer = new byte[1024];
        DatagramPacket receivePacket = new DatagramPacket(receiveBuffer, receiveBuffer.length);
        clientSocket.receive(receivePacket);
        
        String response = new String(receivePacket.getData(), 0, receivePacket.getLength());
        System.out.println("服务器响应: " + response);
        
        clientSocket.close();
    }
}

安全通信(SSL/TLS)

Java通过JSSE(Java安全套接字扩展)支持SSL/TLS安全通信。

SSL服务器示例

import javax.net.ssl.*;
import java.io.*;

public class SslServer {
    public static void main(String[] args) throws Exception {
        SSLServerSocketFactory sslServerSocketFactory = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
        SSLServerSocket serverSocket = (SSLServerSocket) sslServerSocketFactory.createServerSocket(8443);
        
        System.out.println("SSL服务器已启动,等待连接...");
        
        while (true) {
            SSLSocket clientSocket = (SSLSocket) serverSocket.accept();
            System.out.println("SSL客户端已连接");
            
            try (InputStream input = clientSocket.getInputStream();
                 OutputStream output = clientSocket.getOutputStream()) {
                
                byte[] buffer = new byte[1024];
                int bytesRead;
                
                while ((bytesRead = input.read(buffer)) != -1) {
                    String message = new String(buffer, 0, bytesRead);
                    System.out.println("收到客户端消息: " + message);
                    
                    output.write(("SSL服务器收到: " + message).getBytes());
                    output.flush();
                }
            }
        }
    }
}

NIO(非阻塞I/O)技术

NIO(New I/O)是Java 1.4引入的非阻塞I/O模型,用于提高高并发场景下的性能。

NIO文件复制示例

import java.nio.*;
import java.nio.channels.*;
import java.nio.file.*;
import java.io.*;

public class NioFileCopy {
    public static void main(String[] args) throws Exception {
        Path source = Paths.get("source.txt");
        Path target = Paths.get("target.txt");
        
        try (FileChannel sourceChannel = FileChannel.open(source, StandardOpenOption.READ);
             FileChannel targetChannel = FileChannel.open(target, StandardOpenOption.CREATE, StandardOpenOption.WRITE)) {
            
            ByteBuffer buffer = ByteBuffer.allocate(1024);
            
            while (sourceChannel.read(buffer) != -1) {
                buffer.flip();
                targetChannel.write(buffer);
                buffer.clear();
            }
        }
    }
}

实用场景

  1. 简易Web服务器:基于ServerSocket实现,处理HTTP请求
  2. 多人在线聊天系统:服务器端使用多线程处理多个客户端,实现消息广播
  3. 远程数据交换:客户端与服务器端通过Socket进行数据交换
  4. 实时数据传输:如股票行情、实时天气等信息的获取

总结

Java网络编程提供了丰富的API和工具,使开发者能够轻松实现各种网络通信需求。从基础的TCP/UDP编程到高级的SSL安全通信、NIO非阻塞I/O,Java提供了全面的解决方案。通过掌握这些技术,开发者可以构建各种网络应用程序,从简单的客户端-服务器通信到复杂的分布式系统。

Java网络编程的核心在于理解网络通信的基本原理,掌握Socket编程模型,并能灵活运用Java提供的API实现各种网络应用。随着技术的发展,Java的网络编程能力也在不断增强,为开发者提供了更多高效、安全的网络通信解决方案。