当前位置: 首页 > 知识库问答 >
问题:

Java主线程不唤醒ServerSocket接受

顾兴昌
2023-03-14

我正在创建一个简单的web代理应用程序使用Java。基本上,main方法创建一个RequestReceiver对象,该对象具有侦听web浏览器http请求的ServerSocket。从ServerSocket.Accept()返回的套接字创建一个新的连接对象,并将其放入线程池中。

public class RequestReceiver {
    public static final int LISTENING_PORT = 4000;
    public static final int CONNECTION_THREAD_POOL_SIZE = 30;

    private ServerSocket serverSocket;
    private ThreadPoolExecutor connectionThreads;

    public RequestReceiver() throws IOException{
        serverSocket = new ServerSocket(LISTENING_PORT);
        connectionThreads = new ThreadPoolExecutor(CONNECTION_THREAD_POOL_SIZE, CONNECTION_THREAD_POOL_SIZE, 
                1000, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
    }

    public void start(){
        try {
            System.out.println("Current Pool Size: " + connectionThreads.getPoolSize() 
                    + " Active threads: " + connectionThreads.getActiveCount() );
            Connection conn = new Connection(serverSocket.accept());
            System.out.println("Created a new connection thread. Request from " + conn.clientSocketToString());
            connectionThreads.execute(conn);
        } catch (IOException e) {
            System.err.println("Exception occured when accepting a new connection.");
            e.printStackTrace();
        }
    }
}
public class Connection implements Runnable{

public static final int REPLY_CHUNK_SIZE = 32768;
public static final int DEFAULT_WEB_SERVER_PORT = 80;
public static final int SERVER_SOCKET_TIMEOUT = 0; // milliseconds
public static final int CLIENT_SOCKET_TIMEOUT = 0; // milliseconds

private Socket clientSocket, serverSocket;
private InputStream clientIS, serverIS;
private OutputStream clientOS, serverOS;

public Connection(Socket clientSocket){
    this.clientSocket = clientSocket;
    // set client socket timeout
    try{
        clientSocket.setSoTimeout(CLIENT_SOCKET_TIMEOUT);
    }catch(SocketException soe){
        soe.printStackTrace();
    }
}

@Override
public void run() {
    String connection = "";
    try{
        // setup client streams
        clientIS = clientSocket.getInputStream();
        clientOS = clientSocket.getOutputStream();
        // get the request from the browser
        String request = "";
        String hostname = "";
        String[] hostAndPort = new String[2];
        request = browserInputStreamToString(clientIS);
        hostname = getHostName(request);
        hostAndPort = hostname.split(":");
        connection = "Connection to: " + hostname + " from " + clientSocket.getInetAddress().getHostName() 
                + ":" + clientSocket.getPort() + " Request: " + request.split(System.getProperty("line.separator"))[0];
        System.out.println("OPENED>> " + connection);
        // Attempt to create socket to server
        serverSocket = new Socket(hostAndPort[0], (hostAndPort.length > 1 ? new Integer(hostAndPort[1]):DEFAULT_WEB_SERVER_PORT));
        // set timeout
        serverSocket.setSoTimeout(SERVER_SOCKET_TIMEOUT);
        // Set up server streams
        serverIS = serverSocket.getInputStream();
        serverOS = serverSocket.getOutputStream();
        // send client request to server
        serverOS.write(request.getBytes());
        serverOS.flush();
        // send server response to client in chunks
        byte[] reply = new byte[REPLY_CHUNK_SIZE];
        int replyLength = serverIS.read(reply);
        while( replyLength != -1 ){
            clientOS.write(reply, 0, replyLength);
            clientOS.flush();
            replyLength = serverIS.read(reply);
        }
        // close sockets
        clientSocket.close();
        serverSocket.close();
    }catch(Exception e){
        e.printStackTrace();
    } finally{
        try {
            if(clientSocket != null){
                clientSocket.close();
            }
            if(serverSocket != null){
                serverSocket.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    System.out.println("CLOSED>> " + connection);
}

共有1个答案

谷星文
2023-03-14

当你说10中7,你的意思是你测试了10次或几次,得到了这个速率?我这样问是因为默认队列大小是50,所以如果您测试了很多次,您可能会遇到队列问题。如果您没有更改队列大小…

其他的,也是关于队列大小的。您有几个返回和尝试缓存。如果发生任何事情,您将无法到达连接关闭的点。因此,当队列已满时,您将获得超时,直到当前连接关闭。其他相关问题,资源泄漏。

 类似资料:
  • 我想做一个小练习来习惯等待/通知。我想做的是简单地启动一个线程,然后用等待让它进入睡眠状态,用通知唤醒它,多次。 我的代码是: 我希望这会是这样 相反,这样做: 所以。。。通知似乎没有唤醒打印机线程? 这不应该是一个死锁,因为通过等待,我释放了所有的锁,所以主服务器不应该有任何对打印机的锁,打印机应该能够唤醒并打印。 我做错了什么?

  • 问题内容: 哈罗我已经整天调试了我的代码,但是我看不出哪里出了问题。 我在主线程上使用SerialPortEventListener,在工作线程中,我有一个客户端套接字与服务器通信。由于到达此工作线程之后,我仍然需要在主线程中完成一些总结工作,因此我想创建一个“伪线程”,在主线程中等待,直到从侦听器onEvent方法通知它为止。 但是这个伪线程似乎一直在等待。 我检查了锁定的线程,它们在Runna

  • 本文向大家介绍Java多线程基础 线程的等待与唤醒(wait、notify、notifyAll),包括了Java多线程基础 线程的等待与唤醒(wait、notify、notifyAll)的使用技巧和注意事项,需要的朋友参考一下 本篇我们来研究一下 wait() notify() notifyAll() 。 DEMO1: wait() 与 notify() DEMO1 输出: 注意: 使用 wait

  • 我发现当从非主线程启动时,ServerSocket在一定程度上变得不负责任。为什么?当我在主线程中启动ServerSocket时,一切正常。 主要开始类: 启动ServerSocket并接受连接的线程类: 通讯线程: 客户端测试应用程序 启动10个连接的主启动类: 连接Thread: 控制台输出: 客户端测试结果显示并非所有连接都被接受: 服务器控制台仅显示4个接受的连接:

  • 本文向大家介绍怎么唤醒被阻塞的socket线程?相关面试题,主要包含被问及怎么唤醒被阻塞的socket线程?时的应答技巧和注意事项,需要的朋友参考一下 参考回答: 给阻塞时候缺少的资源

  • 问题内容: 我知道我知道,到处已经有上百万个问题和答案。关于它的大量真正详尽的文章,几种示例。我已经花了几个小时阅读有关它的信息,但这并不能解决问题。我之所以这样问,是因为我仍然不安静地理解我需要做的事情,显然是因为我的代码仍然无法正常工作。我想到了Swing如何与EDT一起工作,并且如果要使用ServerSocket的accept()方法,我将需要为Swing启动一个新线程(我认为?)。当我按原