在自己的线程上接受多个同时的客户端套接字 [英] Accepting multiple simultaneous client sockets on their own threads

查看:57
本文介绍了在自己的线程上接受多个同时的客户端套接字的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我做了一些不同的教程,但是没有用,有人可以看到我在做什么吗?

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.

它是通过wifi网络连接的,我需要的是一次有两个或更多的客户端:)

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

推荐答案

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

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.

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

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.

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

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.

这篇关于在自己的线程上接受多个同时的客户端套接字的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆