【问题标题】:Accepting multiple simultaneous client sockets on their own threads在自己的线程上接受多个同时的客户端套接字
【发布时间】:2015-05-29 14:51:52
【问题描述】:

我做了一些不同的教程,但没有任何效果,有人能看出我做错了什么吗?

private volatile boolean keepRunning = true;

public FileSharedServer() {

}

@Override
public void run() {

    try {
        System.out.println("Binding to Port " + PORT + "...");
        // Bind to PORT used by clients to request a socket connection to
        // this server.
        ServerSocket serverSocket = new ServerSocket(PORT);

        System.out.println("\tBound.");
        System.out.println("Waiting for Client...");


        socket = serverSocket.accept();
        System.out.println("\tClient Connected.\n\n");

        if (socket.isConnected()) {
            System.out.println("Writing to client serverId " + serverId
                    + ".");

            // Write the serverId plus the END character to the client thru
            // the socket
            // outStream

            socket.getOutputStream().write(serverId.getBytes());
            socket.getOutputStream().write(END);
        }
        while (keepRunning) {
            System.out.println("Ready");
            // Receive a command form the client
            int command = socket.getInputStream().read();

            //  disconnect if class closes connection
            if (command == -1) {
                break;
            }
            System.out.println("Received command '" + (char) command + "'");

            // decide what to do.
            switch (command) {
            case LIST_FILES:
                sendFileList();
                break;
            case SEND_FILE:
                sendFile();
                break;
            default:
                break;
            }
        }
    } catch (IOException e) {
        System.out.println(e.getMessage());
    } finally {
        // Do not close the socket here because the readFromClient() method
        // still needs to
        // be called.
        if (socket != null && !socket.isClosed()) {
            try {
                System.out.println("Closing socket.");
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

/**
 * This method sends the names of all of the files in the share directory.
 * 
 * @throws IOException
 */
private void sendFileList() throws IOException {
    File serverFilesDir = new File("serverFiles/");
    if (!serverFilesDir.exists() || serverFilesDir.isFile()) {
        System.out.println("'serverfiles' is not an existing directory");
        throw new IOException("'serverfiles' directory does not exist.");
    }
    File[] files = serverFilesDir.listFiles();
    for (File file : files) {
        socket.getOutputStream().write(file.getName().getBytes());
        // Even the last one must end with END and then finally with
        // END_OF_LIST.
        socket.getOutputStream().write(END);
    }
    socket.getOutputStream().write(END_OF_LIST);
}

/**
 * this methods sends a particular file to the client.
 * 
 * @throws IOException
 */
private void sendFile() throws IOException {
    StringBuilder filename = new StringBuilder();
    int character = -1;
    while ((character = socket.getInputStream().read()) > -1
            && character != END && (char) character != END_OF_LIST) {
        filename.append((char) character);
    }
    System.out.println(filename);
    File file = new File(System.getProperty("user.dir")
            + System.getProperty("file.separator") + "serverfiles",
            filename.toString());

    String totalLength = String.valueOf(file.length());
    socket.getOutputStream().write(totalLength.getBytes());
    socket.getOutputStream().write(END);

    FileInputStream fileInputStream = new FileInputStream(file);
    int nbrBytesRead = 0;
    byte[] buffer = new byte[1024 * 2];
    try {
        while ((nbrBytesRead = fileInputStream.read(buffer)) > -1) {
            socket.getOutputStream().write(buffer, 0, nbrBytesRead);
        }
    } finally {
        fileInputStream.close();
    }
}

public static void main(String[] args) throws InterruptedException {
    // Create the server which waits for a client to request a connection.

FileSharedServer server = new FileSharedServer();
System.out.println("new thread");
Thread thread = new Thread(server);

thread.start();


    }

   }    

我需要另一个类还是只需要几行 main?在最底层。

它通过 wifi 网络,我只需要一次两个客户端,或者更多:)

【问题讨论】:

  • 你能比“没有用”更精确吗?怎么了 ?它崩溃了吗?它是否传递了错误的价值观?
  • 它阻止了一个客户端,无法获得两个客户端,一个崩溃或卡住
  • 您应该在接受连接时创建线程,以便您的服务器线程将立即循环回“接受”命令。不确定你做了哪些教程...

标签: java multithreading sockets


【解决方案1】:

这里的问题是您在服务器上只运行一个线程。该线程接受连接,将服务器 ID 写入连接,然后从连接中读取。然后线程继续从连接中读取,直到收到-1,此时线程退出。线程在任何时候都不会尝试接受第二个连接; ServerSocket.accept() 只被调用一次。因此,您只能处理一个客户。

您需要将您的班级分成两个单独的班级。在第一个类中,run() 方法进入一个循环,调用 ServerSocket.accept(),每次该方法返回一个套接字时,都会创建第二个类的实例,将套接字交给它,然后启动它,之后它循环回到 ServerSocket.accept() 调用。

第二个类与您已经编写的类几乎相同,只是它不包含 ServerSocket.accept() 调用。相反,socket 是一个成员变量,由第一个类在启动之前进行初始化。它可以做所有的socket处理,发送服务器ID,接收和处理命令等等,就像你现有的代码一样。

【讨论】:

    猜你喜欢
    • 2023-03-10
    • 2013-02-26
    • 2014-08-18
    • 2010-10-26
    • 2023-03-03
    • 1970-01-01
    • 2018-03-26
    • 1970-01-01
    • 2017-11-05
    相关资源
    最近更新 更多