La manipulation délai de blocage .NET socket
Un TcpClient exemple, créé avec l'Accepter méthode, est utilisé pour gérer un client de connexion. Le problème survient lorsque j'en ai besoin pour terminer le thread du serveur, car il est bloqué sur un appel de réception.
Donc j'ai installé une le TcpClient ReceiveTimeout afin de boucle tous les n millisecondes pour tester la sortie de la condition. Le résultat est que l'opération de réception de lever une exception (exception socketexception), ayant le code de l'erreur SocketError.TimedOut. Bon je pensais...
Le problème est que la propriété Socket.Connecté retourne false, mais comme indiqué dans la documentation MSDN:
La valeur de la propriété Connected reflète l'état de la connexion la plus récente opération. Si vous avez besoin de déterminer l'état actuel de la connexion, effectuer un non bloquantes, de zéro octet Envoyer l'appel. Si les retours d'appel avec succès ou jette un WAEWOULDBLOCK code d'erreur (10035), puis le socket est toujours connecté, sinon, le support n'est plus connecté.
Donc, je fais ce que les états:
try {
//Receive operation on socket stream
//Send operation on socket stream
} catch (SocketException e) {
if (e.SocketErrorCode == SocketError.TimedOut) {
try {
IAsyncResult asyncResult;
int sResult;
asyncResult = mSocket.Client.BeginSend(new byte[] {}, 0, 0, SocketFlags.None, delegate(IAsyncResult result) { }, null);
sResult = mSocket.Client.EndSend(asyncResult);
Debug.Assert(asyncResult.IsCompleted == true);
if (mSocket.Connected == false)
throw new Exception("not more connected"); //Always thrown
} catch (Exception e) {
//...
}
}
Mais, même si le aynch Envoyer opération est exécutée, la propriété mSocket.Connecté est toujours faux, provoquant la boucle externe de résilier (les autres threads appels de méthode de Déconnexion pour mettre fin à la thread du serveur).
Ce qui me manque?
OriginalL'auteur Luca | 2010-08-26
Vous devez vous connecter pour publier un commentaire.
Le problème est que si le délai d'attente se produit le TcpClient est déconnecté. Afin que votre méthode ne fonctionnera pas.
Utilisez la async fonctions de lecture/écriture ou utiliser select.
Le probablement la manière la plus facile avec async appel de fonction comme ceci:
Le code que j'ai posté utilise la async BeginRead/EndRead fonction. Mais il bloque à l'aide de WaitOne. Si vous n'avez pas à changer votre serveur logique. BeginRead ne bloque pas. WaitOne blocs jusqu'à ce qu'il y a des données ou le délai spécifié se produit. À l'aide !résultat.IsCompleted pour vérifier si elle a expiré ou il existe des données disponibles.
Je ne sais pas où "si le délai d'attente se produit le TcpClient est déconnecté" est écrit. Mais j'ai eu exactement le même problème. Et si Lire par retour, le délai d'attente Connecté est Faux. Je n'ai pas fait beaucoup de recherches sur ce sujet, mais simplement accepté qu'il n'est pas prévu en C# pour définir la valeur du délai d'attente et d'exécuter dans ce délai régulièrement.
Je suis d'accord. Cependant, une approche plus simple est d'éviter continu en boucle sur le thread du serveur lors de la manipulation de réseau de communication, de perdre la nécessité d'une fonction de temporisation.
J'ai rencontré le même problème et j'ai essayé cette solution. Toutefois, si aucun d'octets reçus WaitOne sorties après le délai spécifié, mais EndRead blocs jusqu'à ce qu'au moins un octet est reçu ou la connexion est fermée.
OriginalL'auteur pitt7
Consultez ce lien:
Un socket non bloquant opération n'a pas pu être terminé
OriginalL'auteur galbarm
Vous devriez regarder l'exemple en C# sur le Socket.Connecté page MSDN vous liés. Elle est très différente de la mise en œuvre d'une méthode pour déterminer si la prise est toujours connecté.
OriginalL'auteur Chris Shouts