5 Stimmen

Java - Seltsamer hängender Socket?

Ich habe eine Client-Server-Anwendung mit einem Java-Server. Sie funktioniert so gut wie perfekt, außer dass nach einer längeren Zeit plötzlich ein Socket hängen bleibt. Dieser Socket ist nur einer von vielen, die anderen scheinen noch gut zu funktionieren, aber sobald der Server den Socket erreicht, kommt er einfach nicht über die Sendezeile hinaus. Dies sind die relevanten Teile des Codes:

Socket socket; // A normal socket
out  = new PrintWriter(socket.getOutputStream(), true); // The outstream
out.println(msg + "\0"); // This command is used to send stuff, msg is a String

Es werden keine Ausnahmen ausgelöst, die Zeilenanwendung scheint einfach nicht über die Zeile hinauszukommen:

out.println(msg + "\0");

Ich weiß, dass der String gut ist, denn 4 oder 5 andere Steckdosen vor dieser konnten ihn problemlos senden. Soweit ich weiß, könnte dieser Socket auch Hunderte von Nachrichten senden, bevor er sich plötzlich aufhängt. Hat jemand eine Ahnung, auf welche Art von Fehler ich achten sollte?

5voto

jpdaigle Punkte 1245

Es gibt viele Gründe, die dies verursachen können, aber es klingt so, als ob Sie wahrscheinlich auf der TCP-Ebene unter Gegendruck geraten.

Wenn Sie Daten über einen Socket senden, werden diese normalerweise einfach gepuffert und der Sendeaufruf (in Ihrem Fall, println() y flush() ) kann zurückkehren, bevor die Daten tatsächlich an das Netz gesendet werden. Es könnte sein, dass alle vorherigen Schreibvorgänge auf diesem Socket nur in den lokalen Speicher gepuffert wurden. SO_SNDBUF und Sie haben es einfach aufgefüllt.

(1) Können Sie dies mit tcpdump oder Wireshark verfolgen und die genaue Verbindung finden, die hängt (ich weiß, dass dies bei vielen Verbindungen schwierig wird)? Die Untersuchung der TCP-Fenstergröße zu dem Zeitpunkt, an dem sich Ihr Programm aufhängt, wird Ihnen mehr darüber verraten, ob Sie in Java selbst oder auf Netzwerkebene blockiert werden.

(2) Löschen Sie den Stapel und stellen Sie ihn hier ein. Java Sockets haben eine interne Sperre, um zu verhindern, dass zwei Threads gleichzeitig auf sie schreiben können. Sind Sie sicher, dass nur ein Thread auf diesen Socket zugreift, während Sie versuchen, zu schreiben?

Sie sollten auf jeden Fall versuchen, eine

$ jstack <PID>

wenn er eingefroren ist, um genau zu sehen, wo er hängt, und ob der schreibende Thread versucht, irgendwelche Sperren zu erhalten.

3voto

Tim Sylvester Punkte 22343

En Socket das Objekt OutputStream blockiert beim Schreiben unter denselben Bedingungen wie die zugrunde liegende send() Aufruf wird blockiert: wenn die lokalen Socket-Puffer voll sind. Dass er blockiert bleibt, bedeutet, dass der Ausgabepuffer nicht geleert werden kann, was wiederum bedeutet, dass der Lesepuffer am anderen Ende der Verbindung voll ist und dass die Anwendung, die das andere Ende der Verbindung bearbeitet, keine Daten liest, die bereits angekommen sind.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X