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)
編集:無駄にそれを修正するための2番目の試み:
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ページをナビゲートできます。Webページの1つを介してポート番号を変更すると、ポート番号は適切に保存され、ストレージxmlファイルに変更されます。しかし、ソケットを変更して、そのソケットを介してページにすぐに移動すると、ソケットが閉じられており、アプリケーションを再起動するまで機能しないと表示されます。
私はまだこの再起動を回避する方法を探しています。
さて、謎を解きました。スレッドをもう少しうまくサポートするために、クラスを少し再構築する必要がありました。ソケットを閉じてから新しいスレッドを作成する代わりに、新しいスレッドを開始してからソケットを閉じました。少しいじった後、それはうまく機能しているように見えました。
返信などをありがとう。