Ein Schreiben auf einem Socket kann auch blockieren, vor allem, wenn es sich um einen TCP-Socket handelt. Das Betriebssystem puffert nur eine bestimmte Menge nicht übertragener (oder übertragener, aber nicht quittierter) Daten. Wenn Sie etwas schneller schreiben, als die Remote-Anwendung es lesen kann, wird der Socket schließlich gesichert und Ihre write
-Aufrufe werden blockiert.
Reaktion auf diese Folgefragen:
So gibt es einen Mechanismus ein Timeout für diese Einstellung vornehmen? Ich bin mir nicht sicher, was Verhalten es hätte ... vielleicht Daten wegwerfen, wenn Puffer voll sind? Oder möglicherweise ältere Daten im Puffer löschen?
Es gibt keinen Mechanismus zum Festlegen eines Schreib-Timeouts auf einem java.net.Socket. Es gibt eine Socket.setSoTimeout()
Methode, aber es betrifft accept()
und read()
Anrufe ... und nicht write()
Anrufe. Offenbar können Sie Schreib-Timeouts erhalten, wenn Sie NIO, nicht-blockierenden Modus und einen Selektor verwenden, aber das ist nicht so nützlich, wie Sie sich vorstellen können.
Ein korrekt implementierter TCP-Stack verwirft keine gepufferten Daten, es sei denn, die Verbindung wird geschlossen. Wenn Sie jedoch eine Schreib-Zeitüberschreitung erhalten, ist es unsicher, ob die Daten, die sich derzeit in den Puffern auf Betriebssystemebene befinden, am anderen Ende empfangen wurden oder nicht. Das andere Problem ist, dass Sie nicht wissen, wie viel von den Daten von Ihrem letzten write
tatsächlich in TCP-Stapelpuffer des Betriebssystems übertragen wurde. Wenn ein Protokoll der Anwendungsebene zum erneuten Synchronisieren des Streams * nicht vorhanden ist, ist die einzige sichere Maßnahme nach einem Timeout unter write
das Herunterfahren der Verbindung.
Wenn Sie dagegen einen UDP-Socket verwenden, werden die Anrufe write()
nicht für längere Zeit blockiert. Der Nachteil besteht jedoch darin, dass im Falle von Netzwerkproblemen oder wenn die Remote-Anwendung nicht mithalten kann, Nachrichten ohne Benachrichtigung an beide Enden auf dem Boden gelöscht werden. Darüber hinaus stellen Sie möglicherweise fest, dass Nachrichten manchmal nicht ordnungsgemäß an die Remoteanwendung übermittelt werden. Es liegt an Ihnen (dem Entwickler), sich mit diesen Problemen zu befassen.
* Theoretisch ist das möglich, aber für die meisten Anwendungen macht es keinen Sinn, einen zusätzlichen Resynchronisationsmechanismus zusätzlich zu einem bereits zuverlässigen (zu einem bestimmten) TCP/IP-Stream zu implementieren. Und wenn es Sinn macht, müssten Sie auch mit der Möglichkeit umgehen, dass die Verbindung geschlossen wird ... also wäre es einfacher, davon auszugehen, dass es geschlossen ist.
Die Tatsache, dass es nicht eine Timeout-Funktion ist nicht selbst ein Hinweis darauf, dass es nicht blockiert. Ein Hinweis darauf, dass dies der Fall ist, ist das Fehlen eines Rückgabewerts: Wenn er nicht blockiert wird, warum gibt er dann nicht die Anzahl der tatsächlich geschriebenen Bytes zurück? Ein weiterer Hinweis wird gegeben, indem Sie es einfach versuchen. – EJP