java - Java 中的多线程 FTP 服务器

标签 java multithreading

我正在用 Java 制作一个多线程 FTP 服务器,我有一个关于处理多个客户端的问题。现在,我有一个看起来像这样的服务器:

public class Server {
private static final int HOST_PORT = 6000;

private ServerSocket serverSocket;

public Server(ServerModel serverModel) throws IOException {
    serverSocket = new ServerSocket(HOST_PORT);
}

public void start() {
    try {
        acceptClients();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

private void acceptClients() throws IOException {
    while (true) {
        Socket client = serverSocket.accept();
        ServerModel serverModel = new ServerModel();
        Thread worker = new Thread(new ServerWorker(client, serverModel));
        worker.start();
    }
}

还有一个负责解释客户端命令并响应它们的 ServerWorker 对象:

public class ServerWorker implements Runnable {

private ServerRemoteHandler serverRemoteHandler;
private ServerModel serverModel;

private static final int GET_CODE = 1;
private static final int PUSH_CODE = 2;
private static final int CHANGE_DIRECTORY_CODE = 3;
private static final int PRINT_WORKING_DIRECTORY_CODE = 4;
private static final int FILE_EXISTS_CODE = 5;
private static final int LIST_FILES_DIRECTORIES_CODE = 6;
private static final int EXIT_CODE = 0;

public ServerWorker(Socket client, ServerModel serverModel) throws IOException {
    this.serverModel = serverModel;

    try {
        serverRemoteHandler = new ServerRemoteHandler(client);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

private void parseCommand() {
    int command;

    try {
        while (true) {
            command = serverRemoteHandler.getCommand();
            switch (command) {
            case CHANGE_DIRECTORY_CODE:
                changeDirectory();
                break;
            case PRINT_WORKING_DIRECTORY_CODE:
                printWorkingDirectory();
                break;
            case FILE_EXISTS_CODE:
                fileExists();
                break;
            case LIST_FILES_DIRECTORIES_CODE:
                listFilesDirectories();
                break;
            case GET_CODE:
                pushFile();
                break;
            case PUSH_CODE:
                getFile();
                break;
            case EXIT_CODE:
                exit();
                break;
            }
        }
    } catch (IOException e) {
        exit();
    }
}

private void printWorkingDirectory() throws IOException {
    serverRemoteHandler.printWorkingDirectory(serverModel.getCurrentPath());
}

private void changeDirectory() throws IOException {
    String fileName = serverRemoteHandler.getFileName();
    boolean success = serverModel.changeDirectory(fileName);

    serverRemoteHandler.changeDirectory(success);
}

private void fileExists() throws IOException {
    String fileName = serverRemoteHandler.getFileName();
    serverRemoteHandler.fileExists(serverModel.fileExists(fileName));
}

private void pushFile() throws IOException {
    File file = serverModel.getFile(serverRemoteHandler.getFileName());
    long fileSize = serverModel.getFileSize(file);

    serverRemoteHandler.pushFile(file, fileSize);
}

private void listFilesDirectories() throws IOException {
    serverRemoteHandler.listFilesDirectories(serverModel.listFilesDirectories());
}

private void getFile() throws IOException {
    String fileName = serverRemoteHandler.getFileName();
    File file = new File(serverModel.getCurrentPath() + File.separator + fileName);

    serverRemoteHandler.getFile(file);
}

private void exit() {
    serverRemoteHandler.exit();
}

@Override
public void run() {
    while (true) {
        parseCommand();
    }
}

每个 ServerWorker 都有一个名为 RemoteHandler 的对象,其工作是从流中发送和接收信息。我的问题是关于这一行:

Thread worker = new Thread(new ServerWorker(client, serverModel));

这个线程安全吗?这是实现它的好方法吗?谢谢。

最佳答案

是的,它是线程安全的。该行中的所有内容都是方法本地的,因此只能由当前线程访问,然后工作线程启动,同时循环并为这些变量获取一组新值。

(当然,这并不意味着整个程序都是线程安全的。)

关于java - Java 中的多线程 FTP 服务器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49440070/

相关文章:

c# - 事务死锁,如何设计得当?

java - ReentrantLock 用例

java - Spring Security + OAuth,如果访问 token 不存在则回退

java - Java 类(class)主题

java - 打包时如何更改log4j配置

java - 如何在服务器端转义非英文字符

java - 从 Java 7 降级到 Java 6

c# - ThreadPool 错过事件

c - 试图理解c中的死锁

java - 使用 java GUI 的多个时钟