shackleton1986
Messages postés9Date d'inscriptionjeudi 12 janvier 2006StatutMembreDernière intervention21 mars 2007
-
19 mars 2007 à 15:13
shackleton1986
Messages postés9Date d'inscriptionjeudi 12 janvier 2006StatutMembreDernière intervention21 mars 2007
-
21 mars 2007 à 14:01
Je suis en train de faire des tests sur les sockets TCP dans le framework 2.0 et j'ai remarqué quelque chose d'assez curieux...
Je voulais savoir à quel niveau sont renvoyés les exceptions typiquement lorsqu'un cable réseau est arraché ou autre. Pour tester, j'utilise un client telnet sur un PC pour ouvrir un socket avec mon serveur dont le code est ci-dessous. Tout de suite après je déconnecte le PC client du réseau (j'enlève le cable à la barbare ^^), puis je fais des sleep pendant un certain temps voir si j'ai une exception qui est remontée par le framework.
Jusque là, pas d'exception alors que la pile TCP a du se vautrer en raison de l'absence du client qui a été déconnecté sauvagement :) Là je me dis c'est normal, j'aurais une exception la prochaine fois que je veu utiliser mon socket. Du coup je tente de faire un send ... et bingo !!! Aucune exception et le retour du send me dit qu'il a bien envoyé ces octets :s J'essaye même de regarder la valeur "connected" du socket pour voir si j'ai bien quelqu'un en face et il me dit que oui ... :(
Bref, voila mon problème : comment savoir si j'ai toujours quelqu'un en face avec le .net framework ? Et surtout comment savoir quand il me dit que mes données ont bien été envoyées (retour du send) alors que c'est pas le cas ??
Par la suite j'ai essayé d'utiliser la variable SendTimeout du socket mais ca n'a rien changé ...
Voici le code tout bête de mon serveur TCP pour que vous voyez exactement ce que je fais :
Imports System
Imports System.Net
Imports System.Net.Sockets
Imports System.Text
Public Class Form1
Dim port As Integer = 10000
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim sckListening As Socket
Dim sckClient As Socket
sckListening = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
sckListening.Bind(New IPEndPoint(IPAddress.Any, port))
sckListening.Listen(5)
System.Console.WriteLine("Socket en écoute sur " & sckListening.LocalEndPoint.ToString)
sckClient = sckListening.Accept()
System.Console.WriteLine("Serveur: Connexion acceptée avec " & sckClient.RemoteEndPoint.ToString)
'On règle le sois-disant timeout TCP pour l'envoi
sckClient.SendTimeout = 1000
'Là en gros on dort pendant 50 sec pendant qu'on arrache (gentiment) le cable du client
'A chaque sleep on affiche la variable Connected du socket pour voir s'il ya toujours
'quelqu'un en face
Dim i As Integer
For i = 0 To 9
System.Console.WriteLine("Attente de plantage ... " & CStr((i + 1) * 5) & "sec")
System.Console.WriteLine("Socket connecté ? " & sckClient.Connected.ToString)
Threading.Thread.Sleep(5000)
Next
'Maintenant on envoi 6 octets sur le socket qui est mort pour voir si on récupère une
'exception
Dim nbByte As Integer
nbByte = sckClient.Send(Encoding.ASCII.GetBytes("bijour"), 6, SocketFlags.None)
System.Console.WriteLine(CStr(nbByte))
'On a eut aucune exception et la fonction send a envoyer son retour immédiatement
'Mais on fait des sleeps en se disant que le SendTimeout va peut être nous générer
'une exception plus tard
For i = 0 To 9
System.Console.WriteLine("Attente de plantage ... " & CStr((i + 1) * 5) & "sec")
System.Console.WriteLine("Socket connecté ? " & sckClient.Connected.ToString)
Threading.Thread.Sleep(5000)
Next
'Et voilà c'est fini, et on a envoyé des données comme si de rien n'était à un client inexistant
System.Console.WriteLine("Fin")
End Sub
End Class
Egyde
Messages postés158Date d'inscriptionlundi 17 mai 2004StatutMembreDernière intervention16 juillet 2007 20 mars 2007 à 00:26
Intéressant tout ça... J'ai jamais rencontré ce pb (vu que je programme que sous VB6 pour le moment). Cela dit, j'ai trouvé quelques infos qui pourront t'aider certainement. Apparemment, c'est un bug connu chez KroKro :
http://dam.mellis.org/2004/08/net_socket_bugs_gotchas/
shackleton1986
Messages postés9Date d'inscriptionjeudi 12 janvier 2006StatutMembreDernière intervention21 mars 2007 20 mars 2007 à 08:54
Merci beaucoup pour ta réponse, c'est quand même hallucinant ces bugs ...
Je vais essayer de voir comment je peu me débrouiller avec .NET ^^
Je trouve ca dingue que des bugs si importants restent sans correctif --> merci Crosoft :p
En tout cas si quelqu'un a une bidouille pour repérer les déco intempestives de socket je suis preneur !!!
// 10035 == WSAEWOULDBLOCK -> Buffer full for now
if (e.NativeErrorCode.Equals(10035))
{
retState = true;
}
}
finally
{
socket.Blocking = blockingState;
}
return retState;
}
And it's not a bug
Apparement ce n'est pas un bug mais plutôt une "feature" comme dirait un ami à moi ^^ J'ai pas encore testé ce bout de code mais je trouve ca complètement naze que le send soit pas bloquant et qu'on soit obligé de s'écrire une fonction de 20 lignes sortie de derrière les bois pour savoir si son socket est ouvert ...
Egyde
Messages postés158Date d'inscriptionlundi 17 mai 2004StatutMembreDernière intervention16 juillet 2007 21 mars 2007 à 12:55
Que Send n'indique pas la réception correcte des données passe encore. En y réfléchissant bien, ça accélère le trafic dans le sens où on attend pas de confirmation de la part du poste distant.
Mais par curiosité, comme ce n'est visiblement pas l'état courant du socket, j'aimerais bien savoir ce que retourne exactement sckClient.Connected...
Vous n’avez pas trouvé la réponse que vous recherchez ?
shackleton1986
Messages postés9Date d'inscriptionjeudi 12 janvier 2006StatutMembreDernière intervention21 mars 2007 21 mars 2007 à 14:01
Je suis d'accord avec toi, on peut encore accepter que send indique juste que les données on bien été mises dans le tampon. Mais je me demande alors a quoi sert la variable sckClient.Blocking qui par défaut est à True ?? Parcqu'à priori ca ne change rienà première vue. En ce qui concerne le sckClient.connected je ne comprend toujours pas son utilité...
Je me suis un peu penché sur sur la pile TCP windows et il apparait que par défaut, ce n'est qu'au bout de 2 heures (KeepAliveTime) que des "retransmissions" sont effectuées pour tester la présence du tiers distant. Du coup jusqu'à ce timeout la connexion TCP est considéré active par la pile TCP et donc par le Framework. On peut donc simplement s'en aperçevoir quand le tampon est plein et que l'on obtient une exception. Enfin, c'est ce que je pense mais il faut encore que je fasse quelques tests