Java 保持服务器套接字打开

Java 保持服务器套接字打开,java,multithreading,sockets,Java,Multithreading,Sockets,即使抛出错误或异常,我也希望保持套接字服务器处于打开状态 这是我的服务器 编辑: 例如,允许的maxConnection为2,但我使用第三个连接,引发异常java.net.ConnectException:Connection拒绝:connect,我的serversocket关闭 我希望服务器继续运行,直到有地方可用 编辑: 工厂法 public void processRequest(Socket socket,AtomicInteger connectedCount) { try

即使抛出错误或异常,我也希望保持套接字服务器处于打开状态

这是我的服务器

编辑:

例如,允许的maxConnection为2,但我使用第三个连接,引发异常
java.net.ConnectException:Connection拒绝:connect
,我的serversocket关闭 我希望服务器继续运行,直到有地方可用

编辑:

工厂法

public void processRequest(Socket socket,AtomicInteger connectedCount) {
    try
    {

    RequestTreatment requestTreatment= new RequestTreatment(socket,connectedCount);
    Thread threadWorker= new Thread(requestTreatment);
    threadWorker.start();
    }
    finally
    {
        compteurConnexion.incrementAndGet();
        synchronized (connectedCount) {
            connectedCount.notify();
        }
    }

}

}
请求治疗类

public RequestTreatment(Socket socket) {
    super();
    this.socket=socket;

}
@Override
public void run() {
            try
            {
            requestTreatment();
            }
             finally
             {
                try {
                socket.getInputStream().close();
                socket.getOutputStream().close();
                socket.close();
                    } catch (IOException e) {
                e.printStackTrace();
                 }

            }
          }



public void treatment() {
        try {
            in = socket.getInputStream();
            out = socket.getOutputStream();

            // do stuff 

        } catch (IOException e) {
            e.printStackTrace();
             } 
        }
    }

非常感谢

我建议您让您的服务器接受它可以接受的所有连接,并将它们存储在某种列表或映射(最好是线程安全版本)中,并且有一种机制,通过2个线程池一次处理2个连接。当一个进程结束时,您可以从列表中获取最旧的套接字连接并对其进行处理

编辑:

我发现您不想允许第三次连接,因此我将代码更改为:

While(true){
    Socket socket = serveur.accept();
    if(nbClient++< maxConnectionAllowed) factory.processRequest(socket);
    //Else just close the connection and start the loop again
}
While(true){
套接字=serveur.accept();
if(nbClient++
问题就在这里。您正在启动一个新线程来处理套接字,然后在线程仍在运行时,您将进入关闭套接字的最后一个块。因此线程遇到“套接字关闭”异常。请注意,这不是
ServerSocket,
,而是客户机接受的
Socket
。此代码应该在线程代码的最后一个块中,而不是在这里

这里还有一个问题:

public RequestTreatment(Socket socket)
{
    super();
    this.socket=socket;
    threadWorker= new Thread(this);
    threadWorker.start();
}

此代码在完全构建之前泄漏“This”。你不应该在这里启动线程,你应该在执行新请求处理()的地方启动它。

@David Kroukamp谢谢你的回复。是的,我知道,一个简单的while(true)解决了这个问题,但是在我的规范中,我需要将连接限制为同时连接到两个客户端(我不能使用serversocket构造函数,这是一个限制)“抛出异常”java.net.ConnectException:connection拒绝:connect“并且我的serversocket关闭”。不,不是。关闭服务器套接字的唯一方法是关闭它。异常处理程序中的newSocket()方法调用看起来非常虚假。你不会说为什么你只想同时允许两个连接,但是如果你编码正确的话,不管有多少个连接。我不相信这里有一个真正的问题。后来:我费劲地执行了您的代码,这很重要,因为它没有按照发布的方式编译,而且我无法复制
ConnectException
或不需要的
ServerSocket
闭包。正如我在回答中指出的那样,我可以重现其他失败,但你似乎没有问这些。这不是一个真正的问题。
serveur
变量在哪里定义?它是本地的方法类还是主线程类?@EJP首先,感谢您花时间来帮助我。我感谢您的帮助。顺便说一句,我并没有像你想象的那样撒谎。一开始,我启动服务器,然后等待最多2个连接。如果第三个连接到达,将抛出异常“ConnectException”,并关闭服务器(我在ecplise和TaskManager上看到)。现在,感谢您对Gray的帮助,即使我在使用Threads管理连接池时遇到一些问题,我也可以处理此问题。
最后
块似乎位于
Thread
code to me@EJP中。它位于从
run()
方法调用的
treatment()
方法中。“do stuff”在finally的try块中。@EJP感谢您的帮助,但我不理解您说的“此代码在完全构建之前泄漏了‘This’”。这意味着我收到一个空插座?我将用您的更改+灰色更新我的代码,但我不能全部更新,因为我有机密部分(即:请求处理协议)。非常感谢。again@user902509构造函数将“this”作为参数传递给另一个类(父类除外)总是错误的。正在构造的对象尚未完成,因此传递它不可能是正确的。@EJP明白!因为我总是在构造函数中传递它,以便在变量中复制引用。这么说来,这是个坏习惯。
finally{
        try{
            in.close();
            out.close();
            socket.close();
        }
        catch(IOException ioException){
            ioException.printStackTrace();
        }
    }
public RequestTreatment(Socket socket)
{
    super();
    this.socket=socket;
    threadWorker= new Thread(this);
    threadWorker.start();
}