[英]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.