简体   繁体   中英

Accepting multiple simultaneous client sockets on their own threads

I did some different tutorials but nothing works, can someone see what i'm doing wrong?

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


    }

   }    

Do I need another class or just a couple of lines in main? on the very bottom.

It's over a wifi network and all I need is two clients at once, or more :)

The problem here is that you are running only a single thread on the server. This thread accepts a connection, writes the server ID to the connection, then reads from the connection. The thread then continues to read from the connection until a -1 is received, at which point the thread exits. At no point does the thread try to accept a second connection; ServerSocket.accept() is called only once. As a result, you can only handle one client.

What you need is to split your class into two separate classes. In the first class, the run() method goes into a loop, calling ServerSocket.accept(), and each time that method returns a socket, creates an instance of the second class, hands it the socket, and starts it, after which it loops back to the ServerSocket.accept() call.

The second class is almost identical to the class you've already written, except that it doesn't contain the ServerSocket.accept() call. Instead, socket is a member variable which is initialized, by the first class, before it is started. It can do all the handling of the socket, sending the server ID, receiving and handling commands, etc., just as your existing code does.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM