2009-06-30 8 views
6

J'essaye d'abandonner une connexion socket de sorte que le client à l'autre extrémité obtienne un "WSAECONNABORTED (10053) logiciel causé par une interruption de connexion." message d'erreur lorsqu'il interroge la connexion. Close() et Shutdown() se déconnecteront normalement. Je ne veux pas d'une déconnexion gracieuse. Je veux faire un Abort pour que le client détecte que quelque chose a vraiment mal tourné.Comment faire pour abandonner un socket en C#

Merci,

EDIT: Je suis un serveur de codage et je veux abandonner prises pour la connexion des clients

+0

Je ne sais pas comment faire ce que votre demande, mais il semble que le client aurait des attentes à propos de ce qu'il obtiendra via la connexion socket. Si le serveur passe une valeur qui n'a pas de sens pour le client puis s'arrête normalement, cela n'aurait-il pas le même effet que l'abandon de la socket? Par exemple, le client attend une valeur int, le serveur envoie une chaîne puis se ferme. Juste une pensée. – devuxer

+0

Je suis en train de coder un serveur et je veux que le serveur interrompe la connexion si le client envoie des données qui ne répondent pas aux spécifications du protocole. –

+0

duplication possible de [Motifs officiels pour "Abandon de la connexion causée par le logiciel: erreur d'écriture de la socket"] (http://stackoverflow.com/questions/2126607/reasons-reason-for-software-caused-connection-abort-socket-write- Erreur). Cela étant, vous ne pouvez pas le simuler, car il provient de la pile TCP dans des conditions de défaillance du réseau. – EJP

Répondre

2

J'ai réussi à simuler cette situation:

Pour faire une déconnexion gracieuse normale:

vous:

socket.Shutdown(SocketShutdown.Both); 
socket.Close(); 

Cependant, pour faire une Abandonner, vous faites:

socket.Shutdown(SocketShutdown.Send); 
socket.Close(); 

Je pense que la différence est que le client ne recevra pas de paquets ACK et pense que le réinitialisation de l'ordinateur ou quelque chose.

+0

TCP est un protocole bidirectionnel, c'est-à-dire qu'il nécessite la fermeture de la connexion des deux côtés. Ainsi, lorsque vous appelez Shutdown avec "SocketShutdown.Both", il désactive à la fois l'envoi et la réception sur le socket. Cependant, lorsque vous faites "SocketShutdown.Send", le serveur ferme son côté de la connexion TCP. Dans ce scénario, lorsque le client essaie d'envoyer des messages au serveur recevra ECONNABORTED. Jetez un oeil à http://www.chilkatsoft.com/p/p_299.asp pour mieux le comprendre. –

+1

Cela n'entraîne aucune interruption de connexion, encore moins celle de la question OP. Arrêter pour envoyer envoie juste le FIN prématurément, mais il aurait été envoyé par la fermeture de toute façon. Normalement, il n'est pas nécessaire de fermer immédiatement avant de fermer. Il existe un moyen de forcer la réinitialisation d'une connexion, mais je ne vais pas la documenter ici car il y a peu d'utilisations correctes. – EJP

1

si vous tuez le processus, et/ou redémarrer la machine, et/ou débrancher la câble Ethernet, sans appeler Close() et/ou Shutdown()?

+0

vous plaisantez? il veut clairement que le * programme * envoie ECONNABORTED quand une erreur survient.exigeant qu'il plante physiquement le lien/processus du réseau, cela va complètement à l'encontre du but. – muusbolla

+0

Je voulais dire, tuer le processus * other * à l'autre extrémité de la connexion. Il veut que * ce * programme * reçoive * ECONNABORTED de sa pile TCP locale, ce qui (je pense) se produit si la connexion est interrompue (par exemple si l'homologue distant disparaît). – ChrisW

+1

Je suis d'accord avec Chris. Vous ne pouvez pas envoyer le serveur ECONNABORTED au serveur. Ce n'est que lorsque le client verra les Acks manqués pour les données qu'il envoie qu'il recevra ECONNABORTED lors de l'appel suivant. –

-1

essayer d'appeler EndSend() ou EndReceive() en fonction de la situation immédiatement suivie d'une Dispose()

0

Je ne pense pas qu'il est possible d'obtenir le comportement que vous voulez avec la mise en œuvre .Net Socket autres que le client envoie des keep-alives intermittentes. J'ai essayé toutes sortes de choses pour obtenir le comportement que vous avez décrit et j'ai fini par implémenter des messages persistants. Si le serveur Sever appelle Close(), le socket client obtiendra une erreur de connexion annulée la prochaine fois qu'il tentera d'envoyer des données.

-1

Vous pouvez essayer de coder toutes les sockets secondaires dans un autre thread, et le tuer lorsque vous voulez bloquer les connexions.

+2

Cependant, il n'aura pas l'effet désiré. S'il vous plaît ne postez pas de devinettes ici. – EJP

2

Les détails sous-jacents, y compris lorsqu'il est vraiment approprié d'abandonner de force une connexion, sont décrits en détail ici (https://stackoverflow.com/a/13088864/1280848).

La voie C# de le faire est la suivante:

socket.LingerState = new LingerOption(true, 0); 
socket.Close(); 

C'est, utilisez SO_LINGER avec TIME_WAIT = 0

Questions connexes