“java.net.BindException: Address already in use" wenn Sie versuchen, zu erstellen, die gleiche socket mit dem neuen thread als vorige verwendet
Ich arbeite auf Client-Server-simulation in Java, wo Clients (threads) sind die Verbindung zum server zu bekommen, einige Daten. Nach mehreren Sekunden ein zufällig ausgewählter client (thread) getötet werden muss. Ich schließe socket für die Kommunikation verwendeten server-und ließ ihn sterben (durch beenden von run () - Methode). Problem ist, wenn die neu angelegten thread versucht zu erstellen, gleiche Buchse wie vorige verwendet (gleiche Adressen und gleiche ports) zum server zu verbinden, bin ich immer:
java.net.BindException: Address already in use
at java.net.PlainSocketImpl.socketBind(Native Method)
at java.net.AbstractPlainSocketImpl.bind(AbstractPlainSocketImpl.java:374)
at java.net.Socket.bind(Socket.java:627)
at java.net.Socket.<init>(Socket.java:423)
at java.net.Socket.<init>(Socket.java:319)
Code zum erstellen von socket:
private void createNewSocket(InetAddress sIP, int sPort,
InetAddress cIP, int cPort) {
try {
socket = new Socket(sIP, sPort, cIP, cPort);
} catch (IOException e) {
e.printStackTrace();
System.err.println("Socket unsuccessfully created");
}
try {
in = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(
socket.getOutputStream())), true);
} catch (IOException e) {
e.printStackTrace();
try {
socket.close();
} catch (IOException e2) {
System.err.println("Socket unsuccessfully closed");
}
}
}
public void run() {
createNewSocket(gprsServerIP, Util.PORT_SERVER_PORT,
clientIP, sendPort);
out.println(REQUEST);
try {
serverPort = Integer.parseInt(in.readLine());
TCPClient.serverPort[clientID] = serverPort;
System.out.println("Server port: " + serverPort + '\n' +
"Send port: " + sendPort + '\n');
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
socket.close();
} catch (IOException e) {
System.err.println("Socket unsuccessfully closed");
}
}
while (true) {
if (clientID == TCPClient.selectedID) {
TCPClient.selectedID = -1;
createNewSocket(gprsServerIP, Util.PORT_SERVER_PORT,
clientIP, sendPort);
out.println(FREE_PORT + serverPort);
try {
socket.close();
} catch (IOException e2) {
System.err.println("Socket unsuccessfully closed");
}
//System.out.println(socket.isClosed());
System.out.println("Port:" + serverPort + " is free");
TCPClient.id[clientID] = -1;
break;
}
}
clientCount--;
}
- Sie müssen nicht angeben, die client-ip und client-port beim anschließen.. Wenn du weglassen, Sie, es wählt einen verfügbaren port statt
- Kannst du den code für die
run()
Methode? - Ich brauche, um Sie zu benutzen, weil der client wird von VM mit Ubuntu und Server auf Windows 7 und ich muss angeben, client-port und die IP für einige andere Zwecke.
- "Andere Zwecke" wie?
- Vielleicht youe Programm normal ausgeschaltet und die Steckdose ist immer noch gebunden an den Prozess. Das OS tritt der Prozess nach ein paar Minuten. Sie können vermeiden, dass durch die ServerSocket.setReuseAddress(true)
Du musst angemeldet sein, um einen Kommentar abzugeben.
Sind die Chancen, dass der client-socket ist entweder noch in
CLOSE_WAIT
oderTIME_WAIT
- status. Das Betriebssystem stellt sicher, dass alle Daten, die geliefert wurde, unten der Steckdose, bevor eine andere Anwendung wieder verwenden können es. Ansonsten, den neuen client bekommen könnte Müll doppelte Pakete übrig geblieben aus der früheren Verbindung.Ich würde vorschlagen, dass Sie Ihre Kunden arbeiten mit einer Reihe von Anschlüssen, anstatt eine Konstante. Dann können Sie den nächsten port in der Auswahl und Schleife um, wenn Sie erreichen das Ende der Reihe stellen.
Jedoch, wenn Sie nicht benötigen, um den client-port dann sollten Sie nicht setzen Sie den client-port in Ihrem code, an alle, durch die übergabe-port von 0 bis
Socket
. In diesem Fall, JDK und das Betriebssystem, das richtige zu tun, und wählen Sie einen entsprechenden freien port für Sie.Zitiert aus wikipedia:
Wenn ein Prozess stirbt unnatürlich, manchmal der port nicht losgebunden, sofort, und du musst warten, bis ein paar Minuten für den port verfügbar. Wenn möglich, das Programm sollte richtig scheitern (z.B. auch dann, wenn es getötet werden muß, ein shutdown-hook sollte in der Nähe der Steckdose).