[英]java closing a serversocket and opening up the port
我正在创建一个基于Java的服务器。
我正在使用服务器套接字接受传入的消息。
但是,在我的程序中的某些时候,我希望服务器套接字监听另一个端口。
我关闭服务器套接字。 用我的新端口开始一个新的。 一切都好。
但是,当我再次将服务器套接字更改为上一个端口时,它会给我一个错误。
我已经阅读了关闭它后服务器套接字在超时状态下保持一段时间的事情。
所以这是我的问题:我可以绕过服务器套接字的这个超时状态,并在关闭它之后再次使我的端口可用并想再次收听同一个端口吗?
编辑:我的功能是制作和监听服务器套接字和我的功能,使服务器套接字无效并立即创建一个新的服务器套接字
public void makeServerSocketWithPort(int portnr) throws IOException, Exception
{
server = new ServerSocket(portnr);
server.setReuseAddress(true);
while(!portchanged)
{
Socket sock = server.accept();
System.out.println(server.getLocalPort());
System.out.println(sock.getLocalPort());
handler = new Requesthandler(sock); //should be in a thread
System.out.println(server.getLocalPort());
System.out.println(sock.getLocalPort());
}
}
public void invalidateRequestHandler(int newPort)
{
if(server != null)
{
portchanged = true;
try {
server.close();
} catch (IOException ex) {
Logger.getLogger(Controlserver.class.getName()).log(Level.SEVERE, null, ex);
}
}
portchanged = false;
makeServerSocketWithPort(newPort);
}
错误StackTrace:
Exception in thread "main" java.net.SocketException: Socket closed
at java.net.PlainSocketImpl.socketAccept(Native Method)
at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:408)
at java.net.ServerSocket.implAccept(ServerSocket.java:462)
at java.net.ServerSocket.accept(ServerSocket.java:430)
at stuff.Controlserver.makeServerSocketWithPort(Controlserver.java:63)
at stuff.Main.main(Main.java:44)
编辑:第二次尝试修复它无济于事:
public void makeServerSocketWithPort(int portnr, boolean invalidated) throws IOException, Exception
{
if(!invalidated)
{
server = new ServerSocket();
server.setReuseAddress(true);
server.bind(new InetSocketAddress(portnr));
portchanged = false;
}
else
{
//TODO: invalidate the old requestHandler
if(server != null)
{
try
{
server.close();
server = null;
}
catch (IOException ex)
{
Logger.getLogger(Controlserver.class.getName()).log(Level.SEVERE, null, ex);
}
}
if(server.isClosed())
{
System.out.println("closed biatch!");
}
else
{
System.out.println("surprise moddafakkaaaaa!!!");
}
//---------------------------------------------
//then make new requestHandler with new port
portchanged = true;
}
while(!portchanged)
{
if(server != null && !server.isClosed() && !invalidated)
{
Socket sock = server.accept();
System.out.println(server.getLocalPort());
System.out.println(sock.getLocalPort());
System.out.println("test");
handler = new Requesthandler(sock); //should be in a thread
handler.start();
System.out.println("ja harm");
System.out.println(server.getLocalPort());
System.out.println(sock.getLocalPort());
}
else
{
portchanged = true;
}
}
if(portchanged)
{
portchanged = false;
makeServerSocketWithPort(portnr, false);
}
}
再次,这通常很好。 我可以浏览我的html页面。 当我通过其中一个网页更改端口号时,它会在我的存储xml文件中正确存储和更改。 但是,当我更改我的套接字并通过该套接字立即导航到页面时,它表示它已关闭,并且在我重新启动应用程序之前无法正常工作。
我仍然在寻找绕过这种重启的方法。
好吧,我解开了这个谜。 事情是我只需要重新构建我的类,以更好地支持线程。 我没有关闭套接字然后创建一个新线程,而是启动了一个新线程,然后关闭了套接字。 经过一番摆弄后,它似乎工作得很好。
谢谢你的回复和东西。
这是OS的正常服务器套接字行为。 操作系统在WAIT_TIMEOUT状态下保持端口打开。 要解决此问题,请尝试使用ServerSocket.setReuseAddress(boolean on)
。 这将启用/禁用SO_REUSEADDR
套接字选项。 点击此处查看文档。
引用方法setReuseAddress
的javadoc
当TCP连接关闭时,连接可能在连接关闭后的一段时间内保持超时状态(通常称为TIME_WAIT状态或2MSL等待状态)。 对于使用众所周知的套接字地址或端口的应用程序,如果在涉及套接字地址或端口的超时状态中存在连接,则可能无法将套接字绑定到所需的SocketAddress。
在使用bind(SocketAddress)绑定套接字之前启用SO_REUSEADDR允许套接字绑定,即使先前的连接处于超时状态。
使用TCPview查看系统中所有已打开的端口。 您可以关闭正在使用的端口。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.