2009-08-20 2 views
2

Ich habe eine Java-Anwendung mit drei Threads, die jeweils öffnen, einen Socket und eine Verbindung zu einem Server auf anderen Ports. Ich setze so_timeout auf jedem dieser Sockets, nachdem die Verbindung zum Server hergestellt wurde. Danach blockieren die Threads das Warten auf read(). Nur einer der Threads überschreitet das Zeitlimit nach 20 Sekunden (das ist das Zeitlimit, das ich eingestellt habe). Die anderen beiden ignorieren das Timeout. Ist es möglich, dass der TCP-Layer jeweils nur einen Timeout behandelt? Gibt es noch eine andere Erklärung?setSoTimeout auf einem Client-Socket hat keinen Einfluss auf den Socket

+0

Bitte poste deinen Code, du hast vielleicht einen hinterhältigen Logikfehler, der von deiner Frage nicht erfasst werden kann. – Jonathan

+0

Rufen Sie einfach sock.getSoTimeout() auf, um sicherzustellen, dass 20000 zurückgegeben wird. Geben Sie auch einen Code ein. Auf welchem ​​Betriebssystem laufen Sie? – Nick

+0

Hier ist der Code zum Herstellen der Verbindung: während (! Verbunden) { \t versuchen { \t \t client = neue Socket(); \t \t InetSocketAddress sa = neue InetSocketAddress (serverIP, port); \t \t client.connect (sa); \t \t client.setKeepAlive (wahr); \t} catch (UnknownHostException e) { \t \t e.printStackTrace(); \t \t Rückgabewert null; \t} catch (IOException e) { \t ... \t} \t if (client.isConnected()) { \t \t // Setzt Timeout für Leseoperationen blockiert. \t \t versuchen { \t \t \t client.setSoTimeout (Zeitüberschreitung * 1000); \t \t} catch (SocketException e) {} \t \t verbunden = wahr; \t} } – arsenalfan

Antwort

2

The documentation sagt:

Die Option, Eingabe der Sperrvorgang vor muss aktiviert sein Wirkung haben.

vielleicht sollten Sie es vor die Verbindung zum Server hergestellt ist, zumindest eingestellt vor() auf dem Sockel lesen aufrufen.
Aber schwer zu sagen, ohne den Code ...

3

Ich hatte mehrere Probleme in der Vergangenheit Umgang mit SO_TIMEOUT in Windows. Ich glaube, dies ist "angenommen", um die zugrundeliegende Socket-Implementierung, die OS-abhängig sein könnte und mit Registrierungseinstellungen und dergleichen in Konflikt stehen könnte.

Mein Rat ist, nicht SO_TIMEOUT zu verwenden, um eine ausgelöste Ausnahme bei einem Timeout zu erzwingen. Verwenden Sie entweder nicht blockierende E/A oder überprüfen Sie, dass Sie über Bytes verfügen(), bevor Sie() lesen.