ITPub博客

首页 > 应用开发 > IT综合 > Java网络编程深度解析:Socket通信实现与应用实践

Java网络编程深度解析:Socket通信实现与应用实践

投稿 IT综合 作者:bhluo 时间:2026-01-26 15:12:06 0 删除 编辑

# Java网络编程深度解析:Socket通信实现与应用实践


## 网络编程基础与核心概念


Java网络编程建立在TCP/IP协议栈之上,通过抽象的网络API提供跨平台的通信能力。理解网络编程的基础概念是构建可靠网络应用的前提。


```java

// 网络基础工具类

import java.net.InetAddress;

import java.net.NetworkInterface;

import java.util.Enumeration;


public class NetworkUtils {

    

    // 获取本地主机信息

    public static void displayLocalHostInfo() {

        try {

            InetAddress localHost = InetAddress.getLocalHost();

            System.out.println("主机名: " + localHost.getHostName());

            System.out.println("主机地址: " + localHost.getHostAddress());

            System.out.println("Canonical主机名: " + localHost.getCanonicalHostName());

            

            // 检查是否是回环地址

            System.out.println("是否回环地址: " + localHost.isLoopbackAddress());

            

            // 检查是否可到达

            System.out.println("可达性检查: " + localHost.isReachable(3000));

            

        } catch (Exception e) {

            e.printStackTrace();

        }

    }

    

    // 获取所有网络接口

    public static void displayNetworkInterfaces() {

        try {

            Enumeration<NetworkInterface> interfaces = 

                NetworkInterface.getNetworkInterfaces();

            

            while (interfaces.hasMoreElements()) {

                NetworkInterface ni = interfaces.nextElement();

                System.out.println("\n网络接口: " + ni.getName());

                System.out.println("显示名称: " + ni.getDisplayName());

                System.out.println("是否启用: " + ni.isUp());

                System.out.println("是否回环: " + ni.isLoopback());

                

                // 获取接口地址

                Enumeration<InetAddress> addresses = ni.getInetAddresses();

                while (addresses.hasMoreElements()) {

                    InetAddress addr = addresses.nextElement();

                    System.out.println("  地址: " + addr.getHostAddress());

                }

            }

        } catch (Exception e) {

            e.printStackTrace();

        }

    }

    

    // 域名解析

    public static void resolveDomain(String domain) {

        try {

            InetAddress[] addresses = InetAddress.getAllByName(domain);

            System.out.println("域名 " + domain + " 解析结果:");

            

            for (InetAddress addr : addresses) {

                System.out.println("  IP地址: " + addr.getHostAddress());

                System.out.println("  规范主机名: " + addr.getCanonicalHostName());

            }

        } catch (Exception e) {

            System.out.println("解析域名失败: " + e.getMessage());

        }

    }

}

```


## Socket编程基础


### TCP Socket实现


```java

// 基础TCP服务器

import java.io.*;

import java.net.*;


public class BasicTCPServer {

    private ServerSocket serverSocket;

    private int port;

    

    public BasicTCPServer(int port) {

        this.port = port;

    }

    

    public void start() {

        try {

            serverSocket = new ServerSocket(port);

            System.out.println("服务器启动,监听端口: " + port);

            

            while (true) {

                // 接受客户端连接

                Socket clientSocket = serverSocket.accept();

                System.out.println("客户端连接: " + 

                    clientSocket.getInetAddress().getHostAddress() + ":" + 

                    clientSocket.getPort());

                

                // 为每个客户端创建处理线程

                ClientHandler handler = new ClientHandler(clientSocket);

                new Thread(handler).start();

            }

        } catch (IOException e) {

            System.err.println("服务器异常: " + e.getMessage());

        } finally {

            stop();

        }

    }

    

    public void stop() {

        try {

            if (serverSocket != null && !serverSocket.isClosed()) {

                serverSocket.close();

                System.out.println("服务器已关闭");

            }

        } catch (IOException e) {

            System.err.println("关闭服务器时出错: " + e.getMessage());

        }

    }

    

    // 客户端处理类

    private static class ClientHandler implements Runnable {

        private Socket clientSocket;

        private BufferedReader in;

        private PrintWriter out;

        

        public ClientHandler(Socket socket) {

            this.clientSocket = socket;

        }

        

        @Override

        public void run() {

            try {

                // 创建输入输出流

                in = new BufferedReader(

                    new InputStreamReader(clientSocket.getInputStream()));

                out = new PrintWriter(

                    clientSocket.getOutputStream(), true);

                

                String inputLine;

                // 读取客户端消息

                while ((inputLine = in.readLine()) != null) {

                    System.out.println("收到消息: " + inputLine);

                    

                    // 处理消息并回复

                    String response = processMessage(inputLine);

                    out.println(response);

                    

                    if ("exit".equalsIgnoreCase(inputLine)) {

                        break;

                    }

                }

            } catch (IOException e) {

                System.err.println("处理客户端时出错: " + e.getMessage());

            } finally {

                closeConnection();

            }

        }

        

        private String processMessage(String message) {

            // 简单的消息处理逻辑

            if (message.startsWith("echo:")) {

                return "回显: " + message.substring(5);

            } else if (message.startsWith("time")) {

                return "服务器时间: " + new java.util.Date();

            } else if ("help".equalsIgnoreCase(message)) {

                return "支持命令: echo:<消息>, time, help, exit";

            } else {

                return "收到: " + message;

            }

        }

        

        private void closeConnection() {

            try {

                if (in != null) in.close();

                if (out != null) out.close();

                if (clientSocket != null && !clientSocket.isClosed()) {

                    clientSocket.close();

                    System.out.println("客户端连接已关闭");

                }

            } catch (IOException e) {

                System.err.println("关闭连接时出错: " + e.getMessage());

            }

        }

    }

}


// TCP客户端实现

public class TCPClient {

    private Socket socket;

    private BufferedReader in;

    private PrintWriter out;

    private BufferedReader consoleReader;

    

    public void connect(String host, int port) {

        try {

            socket = new Socket(host, port);

            System.out.println("已连接到服务器: " + host + ":" + port);

            

            // 初始化流

            in = new BufferedReader(

                new InputStreamReader(socket.getInputStream()));

            out = new PrintWriter(socket.getOutputStream(), true);

            consoleReader = new BufferedReader(

                new InputStreamReader(System.in));

            

            // 启动接收消息线程

            new Thread(this::receiveMessages).start();

            

            // 发送消息

            sendMessages();

            

        } catch (IOException e) {

            System.err.println("连接失败: " + e.getMessage());

        } finally {

            disconnect();

        }

    }

    

    private void sendMessages() {

        try {

            String userInput;

            while ((userInput = consoleReader.readLine()) != null) {

                out.println(userInput);

                

                if ("exit".equalsIgnoreCase(userInput)) {

                    break;

                }

            }

        } catch (IOException e) {

            System.err.println("发送消息时出错: " + e.getMessage());

        }

    }

    

    private void receiveMessages() {

        try {

            String serverResponse;

            while ((serverResponse = in.readLine()) != null) {

                System.out.println("服务器回复: " + serverResponse);

            }

        } catch (IOException e) {

            System.out.println("连接已断开");

        }

    }

    

    private void disconnect() {

        try {

            if (in != null) in.close();

            if (out != null) out.close();

            if (consoleReader != null) consoleReader.close();

            if (socket != null && !socket.isClosed()) {

                socket.close();

            }

            System.out.println("连接已关闭");

        } catch (IOException e) {

            System.err.println("关闭连接时出错: " + e.getMessage());

        }

    }

    

    public static void main(String[] args) {

        TCPClient client = new TCPClient();

        client.connect("localhost", 8080);

    }

}

```


### UDP Socket实现


```java

// UDP服务器

import java.io.*;

import java.net.*;


public class UDPServer {

    private DatagramSocket socket;

    private int port;

    private boolean running;

    

    public UDPServer(int port) {

        this.port = port;

    }

    

    public void start() {

        try {

            socket = new DatagramSocket(port);

            System.out.println("UDP服务器启动,监听端口: " + port);

            running = true;

            

            // 接收缓冲区

            byte[] buffer = new byte[1024];

            

            while (running) {

                DatagramPacket packet = new DatagramPacket(buffer, buffer.length);

                

                // 接收数据包

                socket.receive(packet);

                

                // 处理数据包

                processPacket(packet);

            }

        } catch (IOException e) {

            System.err.println("服务器异常: " + e.getMessage());

        } finally {

            stop();

        }

    }

    

    private void processPacket(DatagramPacket packet) {

        try {

            String received = new String(

                packet.getData(), 0, packet.getLength(), "UTF-8");

            

            InetAddress clientAddress = packet.getAddress();

            int clientPort = packet.getPort();

            

            System.out.println("收到来自 " + clientAddress.getHostAddress() + 

                             ":" + clientPort + " 的消息: " + received);

            

            // 处理消息

            String response = "UDP响应: " + received.toUpperCase();

            byte[] responseData = response.getBytes("UTF-8");

            

            // 发送响应

            DatagramPacket responsePacket = new DatagramPacket(

                responseData, responseData.length, clientAddress, clientPort);

            socket.send(responsePacket);

            

        } catch (IOException e) {

            System.err.println("处理数据包时出错: " + e.getMessage());

        }

    }

    

    public void stop() {

        running = false;

        if (socket != null && !socket.isClosed()) {

            socket.close();

            System.out.println("UDP服务器已关闭");

        }

    }

}


// UDP客户端

public class UDPClient {

    private DatagramSocket socket;

    private InetAddress serverAddress;

    private int serverPort;

    

    public UDPClient(String host, int port) {

        try {

            socket = new DatagramSocket();  // 随机端口

            serverAddress = InetAddress.getByName(host);

            serverPort = port;

            System.out.println("UDP客户端启动,本地端口: " + socket.getLocalPort());

        } catch (IOException e) {

            System.err.println("初始化客户端失败: " + e.getMessage());

        }

    }

    

    public void sendMessage(String message) {

        try {

            byte[] sendData = message.getBytes("UTF-8");

            DatagramPacket sendPacket = new DatagramPacket(

                sendData, sendData.length, serverAddress, serverPort);

            

            // 发送消息

            socket.send(sendPacket);

            System.out.println("已发送消息: " + message);

            

            // 接收响应

            receiveResponse();

            

        } catch (IOException e) {

            System.err.println("发送消息时出错: " + e.getMessage());

        }

    }

    

    private void receiveResponse() {

        try {

            byte[] buffer = new byte[1024];

            DatagramPacket receivePacket = new DatagramPacket(buffer, buffer.length);

            

            // 设置超时时间

            socket.setSoTimeout(5000);

            

            socket.receive(receivePacket);

            

            String response = new String(

                receivePacket.getData(), 0, receivePacket.getLength(), "UTF-8");

            System.out.println("收到服务器响应: " + response);

            

        } catch (SocketTimeoutException e) {

            System.out.println("接收响应超时");

        } catch (IOException e) {

            System.err.println("接收响应时出错: " + e.getMessage());

        }

    }

    

    public void close() {

        if (socket != null && !socket.isClosed()) {

            socket.close();

            System.out.println("UDP客户端已关闭");

        }

    }

    

    public static void main(String[] args) {

        UDPClient client = new UDPClient("localhost", 9090);

        client.sendMessage("Hello UDP Server!");

        client.close();

    }

}

```


## 高级Socket编程技术


### 非阻塞IO与NIO


```java

// 使用NIO实现非阻塞服务器

import java.io.*;

import java.net.*;

import java.nio.*;

import java.nio.channels.*;

import java.util.*;


public class NIOServer {

    private Selector selector;

    private ServerSocketChannel serverChannel;

    private int port;

    

    public NIOServer(int port) {

        this.port = port;

    }

    

    public void start() {

        try {

            // 打开选择器

            selector = Selector.open();

            

            // 打开服务器通道

            serverChannel = ServerSocketChannel.open();

            serverChannel.configureBlocking(false);  // 非阻塞模式

            

            // 绑定端口

            ServerSocket serverSocket = serverChannel.socket();

            serverSocket.bind(new InetSocketAddress(port));

            

            // 注册接受连接事件

            serverChannel.register(selector, SelectionKey.OP_ACCEPT);

            

            System.out.println("NIO服务器启动,监听端口: " + port);

            

            // 事件循环

            while (true) {

                // 等待事件发生

                int readyChannels = selector.select();

                if (readyChannels == 0) continue;

                

                // 处理就绪的键

                Set<SelectionKey> selectedKeys = selector.selectedKeys();

                Iterator<SelectionKey> keyIterator = selectedKeys.iterator();

                

                while (keyIterator.hasNext()) {

                    SelectionKey key = keyIterator.next();

                    keyIterator.remove();

                    

                    try {

                        if (key.isAcceptable()) {

                            acceptConnection(key);

                        } else if (key.isReadable()) {

                            readData(key);

                        } else if (key.isWritable()) {

                            writeData(key);

                        }

                    } catch (IOException e) {

                        key.cancel();

                        if (key.channel() != null) {

                            key.channel().close();

                        }

                        System.err.println("处理通道时出错: " + e.getMessage());

                    }

                }

            }

        } catch (IOException e) {

            System.err.println("服务器异常: " + e.getMessage());

        } finally {

            stop();

        }

    }

    

    private void acceptConnection(SelectionKey key) throws IOException {

        ServerSocketChannel serverChannel = (ServerSocketChannel) key.channel();

        SocketChannel clientChannel = serverChannel.accept();

        

        if (clientChannel != null) {

            clientChannel.configureBlocking(false);

            

            // 注册读事件

            clientChannel.register(selector, SelectionKey.OP_READ);

            

            System.out.println("接受客户端连接: " + 

                clientChannel.socket().getRemoteSocketAddress());

        }

    }

    

    private void readData(SelectionKey key) throws IOException {

        SocketChannel clientChannel = (SocketChannel) key.channel();

        ByteBuffer buffer = ByteBuffer.allocate(1024);

        

        int bytesRead = clientChannel.read(buffer);

        

        if (bytesRead == -1) {

            // 连接关闭

            System.out.println("客户端断开连接: " + 

                clientChannel.socket().getRemoteSocketAddress());

            clientChannel.close();

            key.cancel();

            return;

        }

        

        if (bytesRead > 0) {

            buffer.flip();

            byte[] data = new byte[buffer.remaining()];

            buffer.get(data);

            

            String message = new String(data, "UTF-8");

            System.out.println("收到消息: " + message);

            

            // 注册写事件以发送响应

            clientChannel.register(selector, SelectionKey.OP_WRITE, message);

        }

    }

    

    private void writeData(SelectionKey key) throws IOException {

        SocketChannel clientChannel = (SocketChannel) key.channel();

        String response = (String) key.attachment();

        

        if (response != null) {

            ByteBuffer buffer = ByteBuffer.wrap(

                ("服务器响应: " + response).getBytes("UTF-8"));

            

            while (buffer.hasRemaining()) {

                clientChannel.write(buffer);

            }

            

            // 重新注册读事件

            clientChannel.register(selector, SelectionKey.OP_READ);

<"eb.jsnjz.cn"><"fb.csxthr.com"><"gb.zhaiLimao.com">

        }

    }

    

    public void stop() {

        try {

            if (selector != null) selector.close();

            if (serverChannel != null) serverChannel.close();

            System.out.println("NIO服务器已关闭");

        } catch (IOException e) {

            System.err.println("关闭服务器时出错: " + e.getMessage());

        }

    }

}

```


### 线程池优化服务器


```java

// 线程池优化的TCP服务器

import java.io.*;

import java.net.*;

import java.util.concurrent.*;


public class ThreadPoolServer {

    private ServerSocket serverSocket;

    private ExecutorService threadPool;

    private int port;

    private int poolSize;

    

    public ThreadPoolServer(int port, int poolSize) {

        this.port = port;

        this.poolSize = poolSize;

    }

    

    public void start() {

        try {

            serverSocket = new ServerSocket(port);

            threadPool = Executors.newFixedThreadPool(poolSize);

            

            System.out.println("线程池服务器启动,监听端口: " + port + 

                             ",线程池大小: " + poolSize);

            

            while (true) {

                Socket clientSocket = serverSocket.accept();

                System.out.println("接受客户端连接: " + 

                    clientSocket.getRemoteSocketAddress());

                

                // 提交任务到线程池

                threadPool.submit(new ClientTask(clientSocket));

            }

        } catch (IOException e) {

            System.err.println("服务器异常: " + e.getMessage());

        } finally {

            stop();

        }

    }

    

    private static 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) {

                    System.out.println("线程 " + Thread.currentThread().getName() + 

                                     " 收到: " + inputLine);

                    

                    // 处理请求

                    String response = handleRequest(inputLine);

                    out.println(response);

                    

                    if ("exit".equalsIgnoreCase(inputLine)) {

                        break;

                    }

                }

            } catch (IOException e) {

                System.err.println("处理客户端时出错: " + e.getMessage());

            } finally {

                try {

                    if (clientSocket != null && !clientSocket.isClosed()) {

                        clientSocket.close();

                    }

                } catch (IOException e) {

                    System.err.println("关闭socket时出错: " + e.getMessage());

                }

            }

        }

        

        private String handleRequest(String request) {

            // 模拟耗时操作

            try {

                Thread.sleep(100);  // 100ms处理时间

            } catch (InterruptedException e) {

                Thread.currentThread().interrupt();

            }

            

            return "处理结果: " + request.toUpperCase();

        }

    }

    

    public void stop() {

        try {

            if (serverSocket != null && !serverSocket.isClosed()) {

                serverSocket.close();

            }

            

            if (threadPool != null) {

                threadPool.shutdown();

                if (!threadPool.awaitTermination(5, TimeUnit.SECONDS)) {

                    threadPool.shutdownNow();

                }

            }

            System.out.println("服务器已关闭");

        } catch (Exception e) {

            System.err.println("关闭服务器时出错: " + e.getMessage());

        }

    }

}

```


## 实际应用案例


### 文件传输服务器


```java

// 文件传输服务器

import java.io.*;

import java.net.*;


public class FileTransferServer {

    private ServerSocket serverSocket;

    private int port;

    

    public FileTransferServer(int port) {

        this.port = port;

    }

    

    public void start() {

        try {

            serverSocket = new ServerSocket(port);

            System.out.println("文件传输服务器启动,监听端口: " + port);

            

            while (true) {

                Socket clientSocket = serverSocket.accept();

                System.out.println("客户端连接: " + 

                    clientSocket.getRemoteSocketAddress());

                

                // 为每个客户端创建处理线程

                new Thread(new FileHandler(clientSocket)).start();

            }

        } catch (IOException e) {

            System.err.println("服务器异常: " + e.getMessage());

        } finally {

            stop();

        }

    }

    

    private static class FileHandler implements Runnable {

        private Socket clientSocket;

        private DataInputStream dataIn;

        private DataOutputStream dataOut;

        

        public FileHandler(Socket socket) {

            this.clientSocket = socket;

        }

        

        @Override

        public void run() {

            try {

                dataIn = new DataInputStream(clientSocket.getInputStream());

                dataOut = new DataOutputStream(clientSocket.getOutputStream());

                

                // 接收命令

                String command = dataIn.readUTF();

                

                if ("UPLOAD".equals(command)) {

                    receiveFile();

                } else if ("DOWNLOAD".equals(command)) {

                    sendFile();

                } else if ("LIST".equals(command)) {

                    listFiles();

                } else {

                    dataOut.writeUTF("未知命令: " + command);

                }

                

            } catch (IOException e) {

                System.err.println("文件传输错误: " + e.getMessage());

            } finally {

                closeConnection();

            }

        }

        

        private void receiveFile() throws IOException {

            // 读取文件名和大小

            String fileName = dataIn.readUTF();

            long fileSize = dataIn.readLong();

            

            System.out.println("开始接收文件: " + fileName + " (" + fileSize + " bytes)");

            

            // 创建文件输出流

            FileOutputStream fileOut = new FileOutputStream("uploads/" + fileName);

            byte[] buffer = new byte[4096];

            long totalRead = 0;

            int read;

            

            // 接收文件数据

            while (totalRead < fileSize && 

                   (read = dataIn.read(buffer)) > 0) {

                fileOut.write(buffer, 0, read);

                totalRead += read;

                

                // 发送进度(可选)

                if (totalRead % (1024 * 1024) == 0) {  // 每1MB报告一次

                    int progress = (int) ((totalRead * 100) / fileSize);

                    System.out.println("接收进度: " + progress + "%");

                }

            }

            

            fileOut.close();

            System.out.println("文件接收完成: " + fileName);

            dataOut.writeUTF("文件上传成功");

        }

        

        private void sendFile() throws IOException {

            // 读取请求的文件名

            String fileName = dataIn.readUTF();

            File file = new File("uploads/" + fileName);

            

            if (!file.exists() || !file.isFile()) {

                dataOut.writeUTF("文件不存在");

                return;

            }

            

            // 发送文件信息和数据

            dataOut.writeUTF("OK");

            dataOut.writeLong(file.length());

            

            FileInputStream fileIn = new FileInputStream(file);

            byte[] buffer = new byte[4096];

            int read;

            

            while ((read = fileIn.read(buffer)) > 0) {

                dataOut.write(buffer, 0, read);

            }

            

            fileIn.close();

            System.out.println("文件发送完成: " + fileName);

        }

        

        private void listFiles() throws IOException {

            File uploadDir = new File("uploads");

            File[] files = uploadDir.listFiles();

            

            if (files == null || files.length == 0) {

                dataOut.writeUTF("无文件");

                return;

            }

            

            StringBuilder fileList = new StringBuilder();

            for (File file : files) {

                if (file.isFile()) {

                    fileList.append(file.getName())

                           .append(" (")

                           .append(file.length())

                           .append(" bytes)\n");

                }

            }

            

            dataOut.writeUTF(fileList.toString());

        }

        

        private void closeConnection() {

            try {

                if (dataIn != null) dataIn.close();

                if (dataOut != null) dataOut.close();

                if (clientSocket != null && !clientSocket.isClosed()) {

                    clientSocket.close();

                }

            } catch (IOException e) {

                System.err.println("关闭连接时出错: " + e.getMessage());

            }

        }

    }

    

    public void stop() {

        try {

            if (serverSocket != null && !serverSocket.isClosed()) {

                serverSocket.close();

            }

            System.out.println("文件传输服务器已关闭");

        } catch (IOException e) {

            System.err.println("关闭服务器时出错: " + e.getMessage());

        }

    }

}


// 文件传输客户端

public class FileTransferClient {

    private Socket socket;

    private DataInputStream dataIn;

    private DataOutputStream dataOut;

    

    public void connect(String host, int port) throws IOException {

        socket = new Socket(host, port);

        dataIn = new DataInputStream(socket.getInputStream());

        dataOut = new DataOutputStream(socket.getOutputStream());

        System.out.println("已连接到文件服务器");

    }

    

    public void uploadFile(String filePath) throws IOException {

        File file = new File(filePath);

        if (!file.exists() || !file.isFile()) {

            System.out.println("文件不存在: " + filePath);

            return;

        }

        

        // 发送上传命令

        dataOut.writeUTF("UPLOAD");

        

        // 发送文件信息

        dataOut.writeUTF(file.getName());

        dataOut.writeLong(file.length());

        

        // 发送文件数据

        FileInputStream fileIn = new FileInputStream(file);

        byte[] buffer = new byte[4096];

        int read;

        

        while ((read = fileIn.read(buffer)) > 0) {

            dataOut.write(buffer, 0, read);

        }

        

        fileIn.close();

        

        // 接收服务器响应

        String response = dataIn.readUTF();

        System.out.println("服务器响应: " + response);

    }

    

    public void downloadFile(String fileName, String savePath) throws IOException {

        // 发送下载命令

        dataOut.writeUTF("DOWNLOAD");

        dataOut.writeUTF(fileName);

        

        // 接收响应

        String response = dataIn.readUTF();

        if (!"OK".equals(response)) {

            System.out.println("下载失败: " + response);

            return;

        }

        

        // 接收文件大小

        long fileSize = dataIn.readLong();

        System.out.println("开始下载文件: " + fileName + " (" + fileSize + " bytes)");

        

        // 接收文件数据

        FileOutputStream fileOut = new FileOutputStream(savePath + "/" + fileName);

        byte[] buffer = new byte[4096];

        long totalRead = 0;

        int read;

        

        while (totalRead < fileSize && (read = dataIn.read(buffer)) > 0) {

            fileOut.write(buffer, 0, read);

            totalRead += read;

        }

        

        fileOut.close();

        System.out.println("文件下载完成: " + fileName);

    }

    

    public void listFiles() throws IOException {

        dataOut.writeUTF("LIST");

        String fileList = dataIn.readUTF();

        System.out.println("服务器文件列表:\n" + fileList);

    }

    

    public void disconnect() {

        try {

            if (dataIn != null) dataIn.close();

            if (dataOut != null) dataOut.close();

            if (socket != null && !socket.isClosed()) {

                socket.close();

            }

            System.out.println("连接已关闭");

        } catch (IOException e) {

            System.err.println("关闭连接时出错: " + e.getMessage());

<"hb.yunruiwater.cn"><"ib.sxyicheng.cn"><"jb.jsnjz.cn">

        }

    }

}

```


### 聊天服务器实现


```java

// 多用户聊天服务器

import java.io.*;

import java.net.*;

import java.util.*;

import java.util.concurrent.*;


public class ChatServer {

    private ServerSocket serverSocket;

    private ExecutorService threadPool;

    private Map<String, ClientHandler> clients;

    private int port;

    

    public ChatServer(int port) {

        this.port = port;

        this.clients = new ConcurrentHashMap<>();

    }

    

    public void start() {

        try {

            serverSocket = new ServerSocket(port);

            threadPool = Executors.newCachedThreadPool();

            

            System.out.println("聊天服务器启动,监听端口: " + port);

            

            while (true) {

                Socket clientSocket = serverSocket.accept();

                ClientHandler handler = new ClientHandler(clientSocket);

                threadPool.submit(handler);

            }

        } catch (IOException e) {

            System.err.println("服务器异常: " + e.getMessage());

        } finally {

            stop();

        }

    }

    

    private class ClientHandler implements Runnable {

        private Socket socket;

        private BufferedReader in;

        private PrintWriter out;

        private String username;

        

        public ClientHandler(Socket socket) {

            this.socket = socket;

        }

        

        @Override

        public void run() {

            try {

                in = new BufferedReader(

                    new InputStreamReader(socket.getInputStream()));

                out = new PrintWriter(socket.getOutputStream(), true);

                

                // 用户注册

                out.println("请输入用户名:");

                username = in.readLine();

                

                // 检查用户名是否已存在

                synchronized (clients) {

                    if (clients.containsKey(username)) {

                        out.println("用户名已存在,请重新连接");

                        return;

                    }

                    clients.put(username, this);

                }

                

                // 广播用户加入

                broadcast(username + " 加入了聊天室");

                System.out.println(username + " 连接: " + socket.getRemoteSocketAddress());

                out.println("欢迎 " + username + "! 输入 /help 查看命令");

                

                // 处理消息

                String message;

                while ((message = in.readLine()) != null) {

                    if (message.startsWith("/")) {

                        handleCommand(message);

                    } else {

                        broadcast(username + ": " + message);

                    }

                }

                

            } catch (IOException e) {

                System.err.println("客户端 " + username + " 连接异常: " + e.getMessage());

            } finally {

                disconnect();

            }

        }

        

        private void handleCommand(String command) throws IOException {

            if (command.equals("/help")) {

                out.println("可用命令:");

                out.println("/help - 显示帮助");

                out.println("/list - 列出在线用户");

                out.println("/whisper <用户名> <消息> - 私聊");

                out.println("/exit - 退出聊天室");

                

            } else if (command.equals("/list")) {

                out.println("在线用户 (" + clients.size() + "):");

                for (String user : clients.keySet()) {

                    out.println("  " + user);

                }

                

            } else if (command.startsWith("/whisper ")) {

                String[] parts = command.split(" ", 3);

                if (parts.length == 3) {

                    String target = parts[1];

                    String msg = parts[2];

                    

                    ClientHandler targetHandler = clients.get(target);

                    if (targetHandler != null) {

                        targetHandler.out.println("【私聊】" + username + ": " + msg);

                        out.println("【私聊】发送给 " + target + ": " + msg);

                    } else {

                        out.println("用户 " + target + " 不在线");

                    }

                } else {

                    out.println("用法: /whisper <用户名> <消息>");

                }

                

            } else if (command.equals("/exit")) {

                throw new IOException("用户退出");

            } else {

                out.println("未知命令: " + command);

            }

        }

        

        private void disconnect() {

            if (username != null) {

                clients.remove(username);

                broadcast(username + " 离开了聊天室");

                System.out.println(username + " 断开连接");

            }

            

            try {

                if (in != null) in.close();

                if (out != null) out.close();

                if (socket != null && !socket.isClosed()) {

                    socket.close();

                }

            } catch (IOException e) {

                System.err.println("关闭连接时出错: " + e.getMessage());

            }

        }

        

        private void broadcast(String message) {

            System.out.println("[广播] " + message);

            for (ClientHandler client : clients.values()) {

                client.out.println(message);

            }

        }

    }

    

    public void stop() {

        try {

            if (serverSocket != null && !serverSocket.isClosed()) {

                serverSocket.close();

            }

            

            if (threadPool != null) {

                threadPool.shutdown();

                if (!threadPool.awaitTermination(5, TimeUnit.SECONDS)) {

                    threadPool.shutdownNow();

                }

            }

            

            // 断开所有客户端

            for (ClientHandler client : clients.values()) {

                client.out.println("服务器关闭");

                client.socket.close();

            }

            clients.clear();

            

            System.out.println("聊天服务器已关闭");

        } catch (Exception e) {

            System.err.println("关闭服务器时出错: " + e.getMessage());

        }

    }

}

```


## 网络编程最佳实践


### 连接管理与异常处理


```java

// 健壮的网络客户端

import java.io.*;

import java.net.*;

import java.util.concurrent.atomic.AtomicInteger;


public class RobustClient {

    private Socket socket;

    private BufferedReader in;

    private PrintWriter out;

    private String host;

    private int port;

    private AtomicInteger retryCount = new AtomicInteger(0);

    private static final int MAX_RETRIES = 3;

    private static final long RETRY_DELAY = 2000;  // 2秒

    

    public RobustClient(String host, int port) {

        this.host = host;

        this.port = port;

    }

    

    public boolean connectWithRetry() {

        while (retryCount.get() < MAX_RETRIES) {

            try {

                socket = new Socket();

                

                // 设置连接超时

                socket.connect(new InetSocketAddress(host, port), 5000);

                

                // 设置读写超时

                socket.setSoTimeout(10000);

                

                // 启用TCP保活机制

                socket.setKeepAlive(true);

                

                // 初始化流

                in = new BufferedReader(

                    new InputStreamReader(socket.getInputStream()));

                out = new PrintWriter(socket.getOutputStream(), true);

                

                System.out.println("成功连接到服务器: " + host + ":" + port);

                retryCount.set(0);

                return true;

                

            } catch (IOException e) {

                retryCount.incrementAndGet();

                System.err.println("连接失败 (" + retryCount.get() + 

                                 "/" + MAX_RETRIES + "): " + e.getMessage());

                

                if (retryCount.get() < MAX_RETRIES) {

                    try {

                        System.out.println("等待 " + RETRY_DELAY/1000 + 

                                         " 秒后重试...");

                        Thread.sleep(RETRY_DELAY);

                    } catch (InterruptedException ie) {

                        Thread.currentThread().interrupt();

                        return false;

                    }

                }

            }

        }

        return false;

    }

    

    public String sendRequest(String request) {

        try {

            out.println(request);

            return in.readLine();

        } catch (SocketTimeoutException e) {

            System.err.println("请求超时: " + request);

            return null;

        } catch (IOException e) {

            System.err.println("发送请求时出错: " + e.getMessage());

            

            // 尝试重新连接

            if (connectWithRetry()) {

                return sendRequest(request);  // 重试请求

            }

            return null;

        }

    }

    

    public void disconnect() {

        try {

            if (in != null) in.close();

            if (out != null) out.close();

            if (socket != null && !socket.isClosed()) {

                socket.close();

            }

            System.out.println("连接已关闭");

        } catch (IOException e) {

            System.err.println("关闭连接时出错: " + e.getMessage());

        }

    }

    

    // 监控连接状态

    public boolean isConnected() {

        return socket != null && 

               socket.isConnected() && 

               !socket.isClosed() && 

               !socket.isInputShutdown() && 

               !socket.isOutputShutdown();

    }

    

    // 心跳检测

    public boolean heartbeat() {

        try {

            String response = sendRequest("PING");

            return "PONG".equals(response);

        } catch (Exception e) {

            return false;

        }

    }

}

```


Java网络编程提供了强大而灵活的工具集,从基础的Socket通信到高级的NIO非阻塞IO,能够满足各种网络应用需求。通过合理的架构设计、线程池管理、异常处理和连接优化,可以构建出稳定高效的网络应用程序。掌握这些核心技术,能够为开发分布式系统、实时通信应用等复杂网络场景奠定坚实基础。


来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/19545/viewspace-3108958/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2015-11-01

  • 博文量
    895
  • 访问量
    934199