1

我正在编写一个带有集成服务器的客户端,该服务器应该无限期地等待新连接 - 并在线程上处理每个连接。

我想在主线程上的系统范围内可用的消息处理程序中处理接收到的字节数组。然而,目前处理显然是在客户端线程上完成的。

我查看了 Futures,ExecutorService 的 submit(),但是当我在服务器中创建客户端连接时,数据将返回到服务器线程。如何从那里将它返回到主线程(可能在同步的数据包存储中?)以在不阻塞服务器的情况下处理它?

我当前的实现如下所示:

    public class Server extends Thread {
    private int port;
    private ExecutorService threadPool;

    public Server(int port) {
        this.port = port;
        // 50 simultaneous connections
        threadPool = Executors.newFixedThreadPool(50);
    }

    public void run() {
        try{
            ServerSocket listener = new ServerSocket(this.port);
            System.out.println("Listening on Port " + this.port);
            Socket connection;

            while(true){
                try {
                    connection = listener.accept();
                    System.out.println("Accepted client " + connection.getInetAddress());
                    connection.setSoTimeout(4000);

                    ClientHandler conn_c= new ClientHandler(connection);
                    threadPool.execute(conn_c);
                } catch (IOException e) {
                    System.out.println("IOException on connection: " + e);
                }
            }
        } catch (IOException e) {
            System.out.println("IOException on socket listen: " + e);
            e.printStackTrace();
            threadPool.shutdown();
        }
    }
}
class ClientHandler implements Runnable {
    private Socket connection;

    ClientHandler(Socket connection) {
        this.connection=connection;
    }

    @Override
    public void run() {
        try {
            // Read data from the InputStream, buffered
            int count;
            byte[] buffer = new byte[8192];

            InputStream is = connection.getInputStream();
            ByteArrayOutputStream out = new ByteArrayOutputStream();

            // While there is data in the stream, read it
            while ((count = is.read(buffer)) > 0) {
                out.write(buffer, 0, count);
            }
            is.close();
            out.close();

            System.out.println("Disconnect client " + connection.getInetAddress());
            connection.close();
            // handle the received data
            MessageHandler.handle(out.toByteArray());
        } catch (IOException e) {
            System.out.println("IOException on socket read: " + e);
            e.printStackTrace();
        }
        return;

    }
}

Update: The robust way seems to be what TomTom suggested - using the newer java.nio instead. As this project is of limited use and more of an experiment, I'd like to know the best way using it with java.io/java.net :)

4

2 回答 2

0

That iwll not scale. Any reason you do that? Plus you waste tons of memory - you dont need a thread PER SOCKET. Use a better Java IO library. Like the one available as part of Java for like 10 years or so (NGIO?). It handles x threads with one socket, just returning data.

于 2010-12-22T07:05:14.793 回答
0

In my option, you can use a sync object to chat with the main thread, after your add client connections to the pool, the main thread can block at the accept and the sync object, after you client handle it, put the processed connection socket and response to a queue, and then wakeup the sync object, so the main thread can then get something from the queue and process it, after main thread handle it, block at accept and wait at the sync object.

Basically, your architecture is a simple/direct way, the newly way is use the java nio, to get the more concurrency server and get better performance, also the nio is not the best way...

于 2010-12-23T09:51:42.787 回答