2013-06-09 9 views
5

po this post, mam ten sam problem i udało mi się go odtworzyć za pomocą prostego testu. Mam nadzieję, że będziesz w stanie mi pomóc.Czas oczekiwania na połączenie po dwóch minutach, chociaż ustawiony na więcej niż dwie minuty

Pozwól mi wyjaśnić, wysyłam wiadomości za pomocą gniazd. Wszystko działa świetnie, dopóki ustawiam opcję taktowania na mniej niż dwie minuty. Ale jeśli ustawię to na więcej niż dwie minuty, gniazdo zostanie wyłączone po dwóch minutach. Tak więc, jeśli ustawię limit czasu na 10 sekund, gniazdo zostanie wyzerowane po 10 sekundach, ale jeśli ustawię to na 180 sekund, gniazdo zostanie wyłączone po 120 sekundach.

Oto przypadek testowy:

import java.io.*; 
import java.net.InetSocketAddress; 
import java.net.ServerSocket; 
import java.net.Socket; 
import java.net.SocketTimeoutException; 

/** 
* 
*/ 
public class TestSocket1 { 

public static void main(String[] args) throws IOException { 

    ServerSocket serverSocket = new ServerSocket(); 

    serverSocket.setReuseAddress(true); 
    serverSocket.bind(new InetSocketAddress(1111), 0); 
    serverSocket.setSoTimeout(1000); 
    Socket socket = null; 

    boolean send = true; 

    while (send) { 
     try { 
      socket = serverSocket.accept(); 
      Thread.sleep(100); 
      String messageReceived = readFromSocket(socket); 

      System.out.println(messageReceived); 

      if (send) { 
       send = false; 

       Thread.sleep(150000); // Causing 2.5 minutes delay 
       // Sending message 

       BufferedWriter wr = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), "UTF8")); 
       PrintWriter printWriter = new PrintWriter(wr, true); 

       String output = "Hello Back"; 

       printWriter.println(output); 
       printWriter.flush(); 
       socket.shutdownOutput(); 

      } 

     } 
     catch (SocketTimeoutException ie) { 
     } 
     catch (Exception e) { 
     } 
     finally { 
      if (socket != null) { 
       socket.close(); 
      } 
     } 
    } 


} 

protected static String readFromSocket(Socket socket) throws IOException { 
    StringBuilder messageReceived = new StringBuilder(); 
    BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8")); 

    String line = br.readLine(); 

    messageReceived.append(line); 

    socket.shutdownInput(); 

    return messageReceived.toString(); 
} 


} 

import java.io.*; 
import java.net.InetSocketAddress; 
import java.net.Socket; 
import java.net.SocketAddress; 

/** 
* 
*/ 
public class TestSocket2 { 

public static void main(String[] args) throws IOException { 

    Socket socket = new Socket(); 
    socket.setKeepAlive(true); 
    socket.setReuseAddress(true); 
    socket.setTcpNoDelay(true); 
    socket.setSoTimeout(180000); // Should wait 3 minutes before throwing time out exception - Actually throwing after 2 minutes 

    SocketAddress socketAddress = new InetSocketAddress(1111); 

    socket.connect(socketAddress, 5000); 

    // Sending message 

    BufferedWriter wr = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), "UTF8")); 
    PrintWriter printWriter = new PrintWriter(wr, true); 

    String output = "Hello There"; 

    printWriter.println(output); 
    printWriter.flush(); 
    socket.shutdownOutput(); 

    String messageReceived = readFromSocket(socket); 

    System.out.println(messageReceived); 

} 

protected static String readFromSocket(Socket socket) throws IOException { 
    StringBuilder messageReceived = new StringBuilder(); 
    BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8")); 

    String line = br.readLine(); 

    messageReceived.append(line); 

    socket.shutdownInput(); 

    return messageReceived.toString(); 
} 


} 

Należy uruchomić klasę TestSocket1 a potem TestSocket2.

Z tym problemem zmagaję się od dłuższego czasu i każda pomoc zostanie doceniona. Dziękuję Ci.

  • EDIT

Więc usunąłem zależność od SO_TimeOut i wziął @Nick sugestię w this post sprawdzić dostępne strumień wejściowy przed odczytaniem. Ale teraz problem polega na tym, że po dwóch minutach dostępne bajty zawsze zwracają 0, mimo że dane wejściowe zostały zapisane w strumieniu. Wciąż mam ten sam problem.

+0

Ja testowałem swój kod na moim laptopie (OS X 10.8.4, JDK 1.6.0_37) i 'TimeoutException' jest generowany po 180 minutach zgodnie z oczekiwaniami. Czy mógłbyś podać wersję OS i wersję JDK? – ericson

+0

OS Windows7 Ultimate SP1 64Bit, JDK jdk1.6.0_26. BTW, jeśli nie jesteś ograniczony do dwóch minut, nie powinieneś widzieć wyjątku TimeoutException. Zauważ, że sen trwa 2,5 minuty, a SoTimeOut jest ustawiony na 3 minuty, więc powinieneś zobaczyć komunikat "Cześć z powrotem". – Rotem

+0

Przepraszam, zapomniałem wspomnieć, że zwiększyłem czas snu do 25 minut, aby odtworzyć "TimeoutException". Nie znam platformy Windows, mam nadzieję, że ktoś mógłby pomóc. – ericson

Odpowiedz

0

więc zorientowali się, jaka była Problem

socket.shutdownInput(); 

przyczyną gniazda, aby zmienić FIN_WAIT zatem stan czekać 2 minuty przed zamknięciem (2MSL)

+0

FIN_WAIT_1 nie powoduje przekroczenia limitu czasu. – EJP

+1

Nie sądzę, że rozumiesz moją odpowiedź. To był problem i mam przypadek testowy, żeby to udowodnić, więc nie rozumiem, dlaczego -1 mnie. – Rotem

1

Nie można zwiększyć limitu czasu połączenia poza domyślną platformę, czyli około minutę. Możesz go tylko zmniejszyć. Próba jej zwiększenia nie ma sensu. Co próbujesz osiągnąć?

+0

OK, na szczęście nie mogłem znaleźć żadnych informacji na temat domyślnych czas oczekiwania na gniazdo w Windows Byłbym wdzięczny, gdybyś mógł dodać link.Po drugie, stan dokumentacji setSoTimeout _A timeout zera jest interpretowany jako nieskończony timeout_, więc skąd mogłem wiedzieć, że jest on ograniczony do domyślnej platformy (ponownie, nie mogłem znaleźć żadnych informacji na ten temat)? Po trzecie, próbuję naprawić błąd w starym systemie, który umożliwia wysyłanie wiadomości między gniazdami, które mogą zająć więcej niż dwie minuty. – Rotem

+0

Javadoc jest oczywiście w błędzie co do limitu czasu połączenia, rzadka okazja. Jeśli nie ustawisz go w ogóle lub ustawisz na zero, na pewno uzyskasz limit czasu połączenia w odpowiednich okolicznościach. Jednak twój komentarz dotyczy limitu czasu * czytania *, co jest inną rzeczą. Możesz ustawić limit czasu odczytu na dowolnie wybrany. Nigdy nie widziałem z tym problemu i regularnie korzystam z limitów czasu czytania gniazd Windows. – EJP

+0

Jawadocs odnosi się do limitu czasu ** read **. Jeśli nigdy nie miałeś problemu z przekroczeniem czasu odczytu gniazd Windows, byłbym wdzięczny, gdybyś mógł uruchomić test i sprawdzić sam. Dziękuję Ci. – Rotem

Powiązane problemy