Jak zapobiec wiązaniu aplikacji Java z gniazdem, do którego inny proces jest już powiązany w systemie Windows?Zapobieganie powiązaniu aplikacji z gniazdem, które jest już powiązane
Mam problem z aplikacją Java, która nasłuchuje na porcie 80. Aplikacja zaczyna działać poprawnie i nie zgłasza żadnych wyjątków. Nie mogłem się domyślić, dlaczego nie mogłem połączyć się z portem 80. Inne porty działały dobrze. Sprawdziłem netstat dla innych procesów nasłuchujących na 80 i znalazłem Skype'a. Nie sądziłem, że to możliwe, ale po pewnych badaniach przypuszczam, że Skype nasłuchuje z opcją SO_REUSEADDR. W tym stanie aplikacja akceptująca jest nieokreślona. Chciałbym, aby moja aplikacja Java nie działała w tym przypadku z wyjątkiem wiązania (lub innym).
Wygląda na to, że mógłbym użyć SO_EXCLUSIVEADDRUSE, gdybym miał dostęp do tej opcji przez Javę, ale nie sądzę, że jest to możliwe. Wokół SO_REUSEADDR jest wiele pytań i odpowiedzi, ale nie znalazłem odpowiedzi na moje pytanie. Nie chodzi tylko o Skype (mogę wyłączyć słuchanie), chcę, aby mój program był bardziej solidny w tej sytuacji.
Jest to urywek z netstat -abn na Windows 7 pudełka:
Proto Local Address Foreign Address State
TCP 0.0.0.0:80 0.0.0.0:0 LISTENING [java.exe]
TCP 0.0.0.0:80 0.0.0.0:0 LISTENING [Skype.exe]
Dlatego jestem przy założeniu, że Skype wykorzystuje SO_REUSEADDR
Procesy nie wydają się być na słuchanie różne interfejsy.
Oto fragment kodu. Port to 80:
myServerSocket = new ServerSocket(myTcpPort);
while (true) {
new HTTPSession(myServerSocket.accept(), threadPool);
}
W ramach dalszych informacji stworzyłem przykładowy program, aby zminimalizować jakiekolwiek efekty uboczne lub niepoprawne wiadomości.
import java.net.ServerSocket;
public class PortTest
{
public static void main(String[] args)
{
System.out.println("Hit Ctrl-C to stop.\n");
try {
ServerSocket myServerSocket = new ServerSocket(80);
System.out.println("Before the accept() call.");
myServerSocket.accept();
System.out.println("After the accept() call.");
}
catch (Exception ex) {
System.out.println("Error listening.");
ex.printStackTrace();
}
}
}
ja nadal nie dostaniesz wyjątek, gdy uruchomiony program przykładowy (PortTest) i gdy Skype działa i nasłuchuje na porcie 80. I do dalszych badań, I wykonany drugą instancję PortTest a ja widzę komunikat port w użyciu.
Error listening.
java.net.BindException: Address already in use: JVM_Bind
at java.net.DualStackPlainSocketImpl.bind0(Native Method)
at java.net.DualStackPlainSocketImpl.socketBind(Unknown Source)
at java.net.AbstractPlainSocketImpl.bind(Unknown Source)
at java.net.PlainSocketImpl.bind(Unknown Source)
at java.net.ServerSocket.bind(Unknown Source)
at java.net.ServerSocket.<init>(Unknown Source)
at java.net.ServerSocket.<init>(Unknown Source)
at PortTest.main(PortTest.java:10)
Czy wiążą swoją ServerSocket do 0.0.0.0 adres? Może twój program Java nasłuchuje na porcie 80 na jednym IP i Skype na innym, wyjaśniając, dlaczego Java nie narzeka na wyjątek PortAlreadyInUse – gma
GMA ma to prawo, po prostu wiąż na 0.0.0.0 i powinieneś dostać "kompletne" powiązanie lub wyjątek. –
Czy możesz opublikować kod inicjujący ServerSocket? – gma