在自己的线程上接受多个同时的客户端套接字

时间:2015-05-29 14:51:53

标签: java multithreading sockets

我做了一些不同的教程,但没有任何作用,有人能看到我做错了吗?

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();


    }

   }    

我需要另一个课程还是主要的几行?在最底层。

这是一个无线网络,我需要的是两个客户端,或者更多:)

1 个答案:

答案 0 :(得分:3)

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

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

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