Nous avons une architecture de serveur client simple entre notre appareil mobile et notre serveur tous deux écrit en Java. Une mise en œuvre extrêmement simple et une mise en oeuvre. Cependant, un problème est que lorsque le client se termine brusquement (sans fermer correctement la prise), le serveur ne sait pas qu'il est déconnecté. De plus, le serveur peut continuer à écrire sur cette prise sans obtenir d'exceptions. Pourquoi? p>
Selon la documentation Les sockets Java devraient lancer des exceptions si vous essayez d'écrire sur une prise qui n'est pas accessible à l'autre extrémité! P>
5 Réponses :
Les communications TCP / IP peuvent être très étranges. TCP réessayera pendant un certain temps aux couches inférieures de la pile sans jamais laisser les couches supérieures savent que quelque chose s'est passé. P>
Je m'attendrais pleinement à cela après une certaine période (30 secondes à quelques minutes), vous devriez voir une erreur, mais je n'ai pas testé cela, je vais simplement sortir de la manière dont les applications TCP ont tendance à travailler. P>
Vous pourriez être capable de resserrer les spécifications TCP (réessayez, le délai d'attente, etc.), mais encore une fois, je n'ai pas beaucoup mal salué. P>
En outre, il se peut que je suis totalement tort et que la mise en œuvre de Java que vous utilisez est simplement floconneuse. P>
La connexion sera éventuellement expirée par Retransmit Timeout (RTO). Cependant, le RTO est calculé à l'aide d'un algorithme compliqué basé sur la latence de réseau (RTT), voir cette RFC, P>
http://www.ietf.org/rfc/rfc2988.txt p>
Donc sur un réseau mobile, cela peut être minutes. Attendez 10 minutes pour voir si vous pouvez obtenir un délai d'attente. P>
La solution à ce type de problème consiste à ajouter un battement de cœur dans votre propre protocole d'application et de déchirure de la connexion lorsque vous ne recevez pas ACK pour le battement de coeur. P>
Le mot clé ici Les prises doivent toujours être acquises et éliminées de cette manière: P> (sans fermer la prise correctement) code>.
final Socket socket = ...; // connect code
try
{
use( socket ); // use socket
}
finally
{
socket.close( ); // dispose
}
Pour répondre à la première partie de la question (à propos de ne pas savoir que le client a déconnecté brusquement), dans TCP, vous ne pouvez pas savoir si une connexion est terminée jusqu'à ce que vous essayiez de l'utiliser. P>
La notion de La livraison garantie dans TCP est assez subtile: La livraison n'est pas réellement garantie à la demande à l'autre extrémité (cela dépend de ce que signifie vraiment garantie). Section 2.6 de RFC 793 (TCP) donne plus de détails sur ce sujet . Ce fil sur la liste de discussion de la Restlet et Pour la deuxième partie (ne détectant pas lorsque vous écrivez sur cette prise), ceci est probablement une question de tampon et de délai d'attente (comme d'autres les ont déjà suggérées). P>
J'ai déjà essayé de l'utiliser en écrivant sur la prise et même je ne sais pas si le client a déconnecté.
Je suis confronté au même problème. Je pense que lorsque vous enregistrez la prise avec un sélecteur, il ne jette aucune exception. Utilisez-vous un sélecteur avec votre prise? P>