web-dev-qa-db-fra.com

Quelle est la fonctionnalité de setSoTimeout et comment ça marche?

J'essaie d'apprendre Socket par moi-même. Je suis un peu confus en suivant le texte du site Web d'Oracle. J'ai quelques questions à ce sujet. Merci d'avance pour toute explication claire.

setSoTimeout

public void setSoTimeout (int timeout) lève SocketException

Activer/désactiver SO_TIMEOUT avec le délai d'expiration spécifié, en millisecondes. Lorsque cette option est définie sur un délai d’expiration différent de zéro, un appel read() sur le InputStream associé à ce Socket ne bloquera que pendant cette durée. Si le délai expire, un Java.net.SocketTimeoutException est levé, même si le socket est toujours valide. L'option doit être activée avant d'entrer dans l'opération de blocage pour avoir effet. Le délai d'expiration doit être> 0. Un délai d'expiration de zéro est interprété comme un délai d'expiration infini.

  1. Qu'est-ce que SO_TIMEOUT?
  2. Socket est le point final d'une connexion. Si je dis

    mySocket.setSoTimeout(2000);
    

    Est-ce que cela signifie que je bloque la lecture de toute entrée du serveur/client pour ce socket pendant 2 000 millisecondes et qu'après cette heure, le socket est prêt à lire des données?

  3. Qu'est-ce que cela signifie que le délai d'attente expire?

  4. Quelle est l'option qui doit être activée avant le blocage?

  5. Infinite Timeout signifie que le socket ne lit plus?

45
Bernard

Le JavaDoc l'explique très bien:

Lorsque cette option est définie sur un délai d’expiration différent de zéro, un appel de read () sur le flux d’entrée associé à ce Socket ne bloquera que pendant cette durée. Si le délai expire, une exception Java.net.SocketTimeoutException est déclenchée, même si le Socket est toujours valide. L'option doit être activée avant d'entrer dans l'opération de blocage pour avoir effet. Le délai d'expiration doit être> 0. Un délai d'expiration de zéro est interprété comme un délai d'expiration infini.

SO_TIMEOUT Est le délai d'attente bloqué par un appel read(). Si le délai est atteint, une Java.net.SocketTimeoutException sera levée. Si vous souhaitez bloquer à jamais mettre cette option à zéro (valeur par défaut), l'appel read() bloquera jusqu'à ce qu'au moins un octet puisse être lu.

30
logoff

Cela signifie-t-il que je bloque la lecture de toute entrée du serveur/client pour ce socket pendant 2 000 millisecondes et qu'après cette heure, le socket est prêt à lire des données?

Non, cela signifie que si aucune donnée n'arrive dans un délai de 2000 ms, un SocketTimeoutException sera lancé.

Qu'est-ce que cela signifie que le délai d'attente expire?

Cela signifie que les 2000 ms (dans votre cas) s'écoulent sans qu'aucune donnée n'arrive.

Quelle est l'option qui doit être activée avant le blocage?

Il n'y en a pas qui "doit être" activé. Si vous voulez dire "peut être activé", c'est l'un d'entre eux.

Infinite Timeout indique que le socket ne lit plus?

Quelle suggestion étrange. Cela signifie que si aucune donnée n'arrive, vous bloquez définitivement la lecture.

35
user207421

Cet exemple m'a tout expliqué:
Comme vous pouvez le constater, setSoTimeout empêche le programme de se bloquer! Il attend pour SO_TIMEOUT temps! s'il ne reçoit aucun signal, il lance une exception! Cela signifie que le temps a expiré!

import Java.io.IOException;
import Java.net.ServerSocket;
import Java.net.Socket;
import Java.net.SocketTimeoutException;

public class SocketTest extends Thread {
  private ServerSocket serverSocket;

  public SocketTest() throws IOException {
    serverSocket = new ServerSocket(8008);
    serverSocket.setSoTimeout(10000);
  }

  public void run() {
    while (true) {
      try {
        System.out.println("Waiting for client on port " + serverSocket.getLocalPort() + "...");
        Socket client = serverSocket.accept();

        System.out.println("Just connected to " + client.getRemoteSocketAddress());
        client.close();
      } catch (SocketTimeoutException s) {
        System.out.println("Socket timed out!");
        break;
      } catch (IOException e) {
        e.printStackTrace();
        break;
      }
    }
  }

  public static void main(String[] args) {
    try {
      Thread t = new SocketTest();
      t.start();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
}
12
Bernard