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