J'ai entendu parler de HTTP Keep-Alive, mais je souhaite pour l'instant ouvrir une connexion socket avec un serveur distant.
Cette connexion de socket restera-t-elle définitivement ouverte ou existe-t-il une limite de délai d'expiration similaire à HTTP persistante?
Les sockets TCP restent ouverts jusqu'à ce qu'ils soient fermés.
Cela dit, il est très difficile de détecter une connexion cassée (cassée, comme si un routeur était mort, etc. par opposition à une connexion fermée) sans réellement envoyer de données. La plupart des applications font donc une sorte de réaction ping/pong de temps en temps juste pour s'assurer que la connexion est toujours vivante.
Vous recherchez l'option de socket SO_KEEPALIVE.
L'API Java Socket expose "keep-alive" aux applications via les méthodes setKeepAlive
et getKeepAlive
.
EDIT: SO_KEEPALIVE est implémenté dans les piles de protocoles réseau du système d’exploitation sans envoi de données "réelles". L’intervalle de maintien en vie dépend du système d’exploitation et peut être paramétré via un paramètre de noyau.
Étant donné qu'aucune donnée n'est envoyée, SO_KEEPALIVE peut uniquement tester la vivacité de la connexion réseau, pas celle du service auquel le socket est connecté. Pour tester ce dernier, vous devez implémenter quelque chose qui implique l'envoi de messages au serveur et l'obtention d'une réponse.
Keepalive TCP et HTTP Keepalive sont des concepts très différents. En TCP, le keepalive est le paquet administratif envoyé pour détecter les connexions obsolètes. Keepalive signifie en HTTP l'état de connexion persistante.
Ceci est de la spécification TCP,
Les paquets persistants NE DOIVENT être envoyés que si aucun paquet de données ou d'accusé de réception n'a été reçu pour la connexion dans un intervalle. Cet intervalle DOIT être configurable et DOIT par défaut être au moins deux heures.
Comme vous pouvez le constater, l'intervalle keepalive TCP par défaut est trop long pour la plupart des applications. Vous devrez peut-être ajouter keepalive dans votre protocole d'application.
Si vous êtes derrière un masque de masquage NAT (comme le sont la plupart des utilisateurs à domicile), le pool de ports externes est limité et ceux-ci doivent être partagés entre les connexions TCP. Par conséquent, les NAT masqués tendent à supposer qu'une connexion a été interrompue si aucune donnée n'a été envoyée pendant une certaine période.
Ceci et d'autres problèmes similaires (n'importe où entre les deux extrémités) peuvent signifier que la connexion ne fonctionnera plus si vous essayez d'envoyer des données après une période d'inactivité raisonnable. Cependant, vous ne pourrez pas le découvrir avant d'essayer d'envoyer des données.
Keepalives à la fois réduit le risque d'interruption de la connexion quelque part sur la ligne et vous permet également de détecter plus tôt une connexion interrompue.
Voici quelques ouvrages supplémentaires sur le Keepalive qui l’expliquent de manière beaucoup plus fine.
http://www.tldp.org/HOWTO/html_single/TCP-Keepalive-HOWTO
Comme Java ne vous permet pas de contrôler les durées Keepalive réelles, vous pouvez utiliser les exemples pour les modifier si vous utilisez un noyau Linux (ou un système d'exploitation basé sur proc).
Dans Java Socket - Les connexions TCP sont gérées au niveau du système d'exploitation, Java.net.Socket ne fournit aucune fonction intégrée permettant de définir les délais d'expiration du paquet keepalive au niveau de chaque socket. Mais nous pouvons activer l’option keepalive pour le socket Java, mais le traitement prend par défaut 2 heures 11 minutes (7200 secondes) après une connexion TCP obsolète. Cette connexion de cause sera disponible très longtemps avant la purge. Nous avons donc trouvé une solution pour utiliser l’interface JNI (Java Native Interface) qui appelle un code natif (c ++) pour configurer ces options.
**** Système d'exploitation Windows ****
Dans le système d'exploitation Windows, keepalive_time et keepalive_intvl peuvent être configurés, mais tcp_keepalive_probes ne peut pas être modifié. Par défaut, lorsqu'un socket TCP est initialisé, le délai de maintien en activité est de 2 heures et l'intervalle de maintien en activité de 1 seconde. La valeur par défaut pour le système du délai persistant est contrôlable via le paramètre de registre KeepAliveTime, qui prend une valeur en millisecondes.
Sous Windows Vista et les versions ultérieures, le nombre de sondes persistantes (retransmissions de données) est défini sur 10 et ne peut pas être modifié.
Sur Windows Server 2003, Windows XP et Windows 2000, le paramètre par défaut pour le nombre de sondes de maintien en activité est 5. Le nombre de sondes de maintien en vie est contrôlable. Pour Windows, la bibliothèque Winsock IOCTLs est utilisée pour configurer les paramètres tcp-keepalive.
int WSAIoctl (SocketFD, // descripteur identifiant une socket SIO_KEEPALIVE_VALS, // dwIoControlCode (LPVOID) lpvInBuffer, // pointeur sur tcp_keepalive struct (DWORD) cbInBuffer, // longueur du tampon d'entrée NULL, // tampon de sortie 0, // taille du tampon de sortie (LPDWORD) lpcbBytesReturned, // nombre d'octets renvoyés NULL, // structure OVERLAPPED NULL // routine d'achèvement);
OS Linux
Linux a un support intégré pour Keepalive qui doit permettre l’utilisation du réseau TCP/IP pour pouvoir l’utiliser. Les programmes doivent demander un contrôle keepalive pour leurs sockets à l'aide de l'interface setsockopt.
int setsockopt (int socket, int level, int optname, const void * optval, socklen_t optlen)
Chaque socket client sera créé à l'aide de Java.net.Socket. L'ID de descripteur de fichier pour chaque socket sera récupéré à l'aide de la réflexion Java.
Pour Windows selon Microsoft docs