这是一个简单的Java聊天服务器,实现文件传输功能。服务器使用ServerSocket对象监听端口17500,在接收到客户端连接后,使用新线程处理客户端请求,并通过SocketUtil类中的outByFile方法发送文件给客户端。

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

public class ChatServer {
    public static void main(String[] args) throws IOException {
        // 创建ServerSocket对象,监听端口17500
        ServerSocket serverSocket = new ServerSocket(17500);
        System.out.println('服务器已启动,正在监听端口 ' + serverSocket.getLocalPort() + ' ...');

        while (true) {
            // 接收客户端连接,创建Socket对象
            Socket socket = serverSocket.accept();
            System.out.println('接收到来自 ' + socket.getInetAddress().getHostAddress() + ':' + socket.getPort() + ' 的连接。');

            // 启动新线程处理客户端请求
            new Thread(() -> {
                try {
                    // 创建SocketUtil对象
                    SocketUtil socketUtil = new SocketUtil(socket);

                    // 发送文件并等待客户端断开连接
                    socketUtil.outByFile('data');

                    System.out.println('成功发送文件给 ' + socket.getInetAddress().getHostAddress() + ':' + socket.getPort() + ' 。');
                } catch (IOException e) {
                    System.err.println('处理客户端请求时出现异常:' + e.getMessage());
                }
            }).start();
        }
    }

    static class SocketUtil {
        private InputStream is;
        private OutputStream os;

        public SocketUtil(Socket socket) throws IOException {
            // 获取输入输出流
            this.is = socket.getInputStream();
            this.os = socket.getOutputStream();
        }

        public void outByFile(String filePath) throws IOException {
            String path = ChatServer.class.getResource(filePath).getPath();
            FileInputStream fis = null;
            try {
                // 读取文件内容,并写入输出流
                fis = new FileInputStream(path);
                byte[] buffer = new byte[8129];
                int len;
                while ((len = fis.read(buffer)) != -1) {
                    os.write(buffer, 0, len);
                }
                os.flush();

                // 等待客户端断开连接
                while (is.available() > 0) {
                    Thread.sleep(100);
                }
            } catch (FileNotFoundException e) {
                System.err.println('文件 ' + filePath + ' 不存在。');
            } catch (IOException e) {
                System.err.println('发送文件 ' + filePath + ' 时出现异常:' + e.getMessage());
            } catch (InterruptedException e) {
                System.err.println('等待客户端断开连接时出现异常:' + e.getMessage());
            }
        }
    }
}

优化建议

  1. 建议将服务器IP和端口作为参数传递给程序,而不是硬编码。
  2. 建议设置超时时间,如果超时则关闭连接,防止客户端无法断开连接导致服务器一直等待。
  3. 在处理异常时,建议将异常信息记录到日志文件中,而不是仅仅输出到控制台。

代码改进

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

public class ChatServer {
    public static void main(String[] args) throws IOException {
        if (args.length != 2) {
            System.err.println('请提供服务器IP和端口号作为参数!');
            System.exit(1);
        }
        String ip = args[0];
        int port = Integer.parseInt(args[1]);

        // 创建ServerSocket对象,监听端口
        ServerSocket serverSocket = new ServerSocket(port, 0, InetAddress.getByName(ip));
        System.out.println('服务器已启动,正在监听端口 ' + serverSocket.getLocalPort() + ' ...');

        while (true) {
            // 接收客户端连接,创建Socket对象
            Socket socket = serverSocket.accept();
            System.out.println('接收到来自 ' + socket.getInetAddress().getHostAddress() + ':' + socket.getPort() + ' 的连接。');

            // 启动新线程处理客户端请求
            new Thread(() -> {
                try {
                    // 创建SocketUtil对象
                    SocketUtil socketUtil = new SocketUtil(socket);

                    // 发送文件并等待客户端断开连接
                    socketUtil.outByFile('data', 10000);

                    System.out.println('成功发送文件给 ' + socket.getInetAddress().getHostAddress() + ':' + socket.getPort() + ' 。');
                } catch (IOException e) {
                    System.err.println('处理客户端请求时出现异常:' + e.getMessage());
                    // 记录异常信息到日志文件
                    // ...
                }
            }).start();
        }
    }

    static class SocketUtil {
        private InputStream is;
        private OutputStream os;

        public SocketUtil(Socket socket) throws IOException {
            // 获取输入输出流
            this.is = socket.getInputStream();
            this.os = socket.getOutputStream();
        }

        public void outByFile(String filePath, int timeout) throws IOException {
            String path = ChatServer.class.getResource(filePath).getPath();
            FileInputStream fis = null;
            try {
                // 读取文件内容,并写入输出流
                fis = new FileInputStream(path);
                byte[] buffer = new byte[8129];
                int len;
                while ((len = fis.read(buffer)) != -1) {
                    os.write(buffer, 0, len);
                }
                os.flush();

                // 等待客户端断开连接,设置超时时间
                long endTime = System.currentTimeMillis() + timeout;
                while (is.available() > 0 && System.currentTimeMillis() < endTime) {
                    Thread.sleep(100);
                }
                // 超时则关闭连接
                if (System.currentTimeMillis() >= endTime) {
                    socket.close();
                    System.err.println('客户端连接超时,已关闭连接。');
                }
            } catch (FileNotFoundException e) {
                System.err.println('文件 ' + filePath + ' 不存在。');
            } catch (IOException e) {
                System.err.println('发送文件 ' + filePath + ' 时出现异常:' + e.getMessage());
            } catch (InterruptedException e) {
                System.err.println('等待客户端断开连接时出现异常:' + e.getMessage());
            } finally {
                if (fis != null) {
                    fis.close();
                }
            }
        }
    }
}

代码说明

  1. 使用命令行参数传递服务器IP和端口号。
  2. 在SocketUtil类的outByFile方法中设置超时时间,如果超时则关闭连接。
  3. 使用finally块关闭FileInputStream,避免资源泄漏。

通过以上改进,可以提升服务器的稳定性和安全性。

Java聊天服务器:文件传输实现与优化建议

原文地址: https://www.cveoy.top/t/topic/lHdV 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录