begin process at 2010 09 06 03:38:49
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

Réseau & Internet

 > AUTOSOCKET, UN CLONE DU CONTRÔLE WINSOCK EN .NET

AUTOSOCKET, UN CLONE DU CONTRÔLE WINSOCK EN .NET


 Information sur la source

Note :
9,29 / 10 - par 14 personnes
9,29 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10
Catégorie :Réseau & Internet Source .NET ( DotNet ) Niveau :Débutant Date de création :03/02/2004 Date de mise à jour :10/05/2004 16:39:45 Vu / téléchargé :15 354 / 2 443

Auteur : Xya

Ecrire un message privé
Commentaire sur cette source (61)
Ajouter un commentaire et/ou une note

 Description

Cliquez pour voir la capture en taille normale
Dans le Framework .NET, il ya une classe Socket dans l'espace de noms System.Net.Sockets.Socket qui marche bien, mais qui ne lance pas d'événements. Il faut en permanence vérifier l'état du socket, c'est à dire si des données sont disponibles, s'il y a une connexion en attente... AutoSocket est donc une classe qui expose les méthodes les plus utilisées de la classe Socket (Send, Connect, Listen, etc), tout en la simplifiant avec des événements. L'événement Close se produit quand le socket se déconnecte, avec un message de l'erreur s'il y en a une; l'événement DataArrival, semblable à celui du contrôle WinSock qui se produit quand des données arrivent et l'événement Connect qui est explicite. L'utilisation des événements permet de simplifier beaucoup la classe socket: pas besoin de vérifier les connexions en attente et d'appeller Accept(), ni de vérifier les données disponibles, tout est automatique.

Source

  • 'Pour utiliser le socket
  • 'client:
  • Dim socket As New AutoSocket()
  • 'pour se connecter:
  • socket.Connect( New IPEndPoint( IPAddress.Parse("<adresse IP>"), <port> ))
  • 'server
  • Dim socket As New AutoSocket( New IPEndPoint( IPAddress.Parse("<adresse IP locale>"), <port> ) )
  • 'pour se mettre en écoute:
  • socket.Listen()
  • 'client/server
  • 'pour envoyer des données:
  • Dim data As Byte()
  • socket.Send( data )
  • 'pour recevoir des données:
  • AddHandler socket.DataArrival, socket_DataArrival
  • Private Sub socket_DataArrival( sender As Object, data As Byte() )
  • 'utiliser les données
  • End Sub
  • 'pour voir la progression de l'envoi:
  • AddHandler socket.DataDeparture, socket_DataDeparture
  • AddHandler socket.SendComplete, socket_SendComplete
  • Private Sub socket_DataDeparture( sender As Object, e as DataDepartureEventArgs )
  • 'envoyé e.CurrentBytesSent sur e.TotalBytes
  • End Sub
  • Private Sub socket_SendComplete( sender As Object, e as EventArgs )
  • 'l'envoi est terminé
  • End Sub
'Pour utiliser le socket

'client:
Dim socket As New AutoSocket()
'pour se connecter:
socket.Connect( New IPEndPoint( IPAddress.Parse("<adresse IP>"), <port> ))

'server
Dim socket As New AutoSocket( New IPEndPoint( IPAddress.Parse("<adresse IP locale>"), <port> ) )
'pour se mettre en écoute:
socket.Listen()

'client/server

'pour envoyer des données:
Dim data As Byte()
socket.Send( data )

'pour recevoir des données:
AddHandler socket.DataArrival,  socket_DataArrival

Private Sub socket_DataArrival( sender As Object, data As Byte() )
     'utiliser les données
End Sub

'pour voir la progression de l'envoi:
AddHandler socket.DataDeparture, socket_DataDeparture
AddHandler socket.SendComplete, socket_SendComplete

Private Sub socket_DataDeparture( sender As Object, e as DataDepartureEventArgs )
     'envoyé e.CurrentBytesSent sur e.TotalBytes
End Sub

Private Sub socket_SendComplete( sender As Object, e as EventArgs )
     'l'envoi est terminé
End Sub

 Conclusion

La classe AutoSocket peut être améliorée mais toute la base pour écouter les événements de sockets est présente et testée, il est facile d'ajouter un événement, comme par exemple l'arrivée de données hors-bande ou la fin d'un envoi de données.

 Fichier Zip

Les Membres Club peuvent télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip


 Sources du même auteur

Source avec Zip Source avec une capture Source .NET (Dotnet) APILEECH: DÉCOMPILATEUR D'APPELS AUX APIS DANS UN ASSEMBLY ....
Source .NET (Dotnet) RÉSOUDRE LE NOM D'UN FICHIER OU D'UN RÉPERTOIRE
Source avec Zip Source avec une capture Source .NET (Dotnet) LONGARRAYLIST: CRÉER UN ARRAYLIST TYPÉ DE TOUTES PIÈCES
Source avec Zip Source avec une capture Source .NET (Dotnet) NMAKE VB.NET: COMPILATEUR DE PROJETS VB.NET SANS VISUAL STUD...

 Sources de la même categorie

Source avec Zip Source avec une capture Source .NET (Dotnet) CHATIRC - UN CLIENT IRC SIMPLE par raffika
Source avec Zip Source avec une capture GOOGLE EARTH IN VB6 par ZaidMarkabi
Source avec Zip Source .NET (Dotnet) VB10! COLOMB TEAM GORILLA BROWSER par Ultrabytes
Source avec Zip Source avec une capture Source .NET (Dotnet) COMMUNICATION TCP CLIENT-SERVEUR ASYNCHRONE par anadom
Source avec Zip Source avec une capture Source .NET (Dotnet) CLIENT IRC QUI LIT À VOIX HAUTE par pigedanslelac

Commentaires et avis

Commentaire de mahhoura le 05/02/2004 10:10:59

Voila 10 points :) continue!

Commentaire de Xya le 05/02/2004 13:33:04

Merci de mettre un commentaire avec la note, c'est toujours frustrant d'avoir une note sans commentaire, de pas savoir ce qui doit être amélioré/changé/ajouté :)


Xya

Commentaire de Kitsu le 29/02/2004 01:55:00

C'est plutot bien monté, mais je regrette qu'il y est des appels sur ws2_32.dll ca va un peu à l'encontre du système de prog. .NET.

Comme c'est dit dans la Classe d'ailleurs :) "Unsafe"

Je pense qu'une autre version du Composant pourrait se contenter de ce qu'offre le Framework en standard et offrir des interfaces plus sympa pour la gestion du stream.

Sinon c bien :)

Commentaire de Xya le 29/02/2004 20:13:46

Ben tant que le Framework .NET ne propose pas des classes de remplacement à toute l'API de Windows il faudra faire comme ca, en attendant Indigo de Longhorn.

Sinon si tu décompile le code du Framework tu vois qu'un grand nombre de classes sont juste des wrappers qui utilisent massivement les appels à l'API de Windows (Socket, FileStream, System.Windows.Forms, System.Threading, System.Security.Cryptography, Microsoft.Win32 (là c'est normal :p), GDI+, etc), mais je suis d'accord avec toi qu'il faut plutot écrire du code portable, par exemple pour pouvoir être exécuté sur Mono.

Sinon pour la classe AutoSocket j'ai réussi à un peu l'améliorer, à savoir se débarasser du thread qui dispatche les événements, en utilisant les événements de Windows (les classes Auto/Manual-ResetEvent) et RegisterWaitForSingleObject de ThreadPool: en fait, j'avais pas remarqué que les events WinSock étaient des bêtes events de Windows :)

Faut que je mette à jour le zip.


Xya

Commentaire de irchk le 08/03/2004 16:09:01

Arf, bon moi je suis un sti nouveau concernant .net, et je dois retranscrire ce que faisiait le controle winsock....

Ca tombe bien, le post qu'il me fallait MAIS...j'arrive pas a trouver le namespace de la classe autosocket...surtout que je trouve null part un sti renseignement sur cette classe...

Merci pour toutes infos sup !

Commentaire de irchk le 08/03/2004 16:48:26

Autant pour moi, j'avais pas vu qu'il y'avait un zip...dur dur le lundi

Commentaire de Xya le 08/03/2004 21:59:24

Voilà j'ai mis à jour le zip avec la version simplifiée de SocketEventSink (utilisation de la classe AutoResetEvent au lieu des APIs Winsock et disparition du thread de travail). J'ai aussi changé l'espace de noms, les classes sont maintenant dans System.Net.Sockets au lieu de Sockets.



Xya

Commentaire de cognicase le 26/03/2004 02:11:36

C'est super bien ... moi j'aime bien ..
Un petit ajout serait de permettre plusieurs connection sur le serveur avec un nom d'usager comme le fait MSN pis ca y est tu aurais refait MSN .... avec .net ...

Commentaire de djmoha2000 le 13/04/2004 14:00:35

ca fais plus de 3 jours que je cherche un code pareil,surtout que j'avais l'habitude de travailler avec vb6(qui est différent).
cependant ca serait interssant de permettre plrs con vers serveur(comme suggéré par cognicasse),ds ce cas soit il faut résoudre le prob des index(groupe de control en vb6),soit utiliser des thread(chaque requéte entrante sera un nouvel thread) sinon creer des instances(à chaque reéception coté serveur) d'un objet socket(par exemple).je travaille actuellement la dessus.
sinon,bon courage et merçi

Commentaire de dionysos6868 le 20/04/2004 14:32:47

Merci a toi je cherche a mettre mon ordi en ecoute sur le net d'en voyer une page html au client pour transmettre des ordre a l'ordi serveur je pense que ton zip va mettre utilie j'espere

merci

Commentaire de dionysos6868 le 20/04/2004 15:00:05

perso ca ne marche pas soit disant que ma version de .net n'est pas assez ressente pour ouvrire ton projet

si tu a une idée a me propose merci de m'en faire part msn dionysos6868@hotmail.com

merci de ton aide

Commentaire de Xya le 21/04/2004 06:24:36

Ce que tu peux faire c'est créer un projet VB.NET appellé AutoSocket avec les paramètres suivants:

Type: bibliothèque de classes
Espace de noms racine: System.Net.Sockets
Objet de démarrage: aucun
Option Explicit On
Option Strict Off

et tu ajoutes à ce projet les fichiers sources .vb présents dans le zip.
Ca devrait marcher.


Xya

Commentaire de dionysos6868 le 21/04/2004 15:13:27

Merci de ton aide.

Saurais tu egalement svp comment je pourrais fair pour envoyer des information sur une ecoute de socket apartire d'un page web et avoir un retour

Par exemple sur une page web avoir le listing des processus en route sur mon ordi et d'envoyer l'ordre de fermer tel ou tel processus.

merci

Commentaire de Xya le 21/04/2004 17:47:58

Je pense que tu devrais faire un mini serveur web qui  puisse répondre aux reqêtes simples (GET) et générer du html pour la liste des processus en cours. Il y a quelques exemples de serveurs web en VB sur VBFRance, tu pourais t'en inspirer.
Après tu peux facilement acceder à ta liste avec un navigateur.

http://[ip ou nom  de l'ordi]:[port ouvert par le serveur web]/[page web à générer]

Par exemple:

http://dionysos:80/listprocess.html
http://dionysos:80/lkillprocess.html?pid=123


J'espère que ça peut t'aider.


Xya

Commentaire de TigerFab le 09/05/2004 23:32:35

Très très belle source et très bon travail !

Mais j'ai 2 questions ;

- System.net.socket remplace bien winsock de VB6 ? pq ils ont pas prévu les évènements (indispensables) de Winsock alors ? ou faut-il pour ca utiliser une autre classe ?
- tu n'as pas fait l'évènement SendProgress disponible dans WinSock. C'est facile à ajouter ?

Commentaire de Xya le 10/05/2004 13:15:25

Voilà, suite à ta demande TigerFab j'ai ajouté les événements DataDeparture (envoi en cours) et SendComplete (envoi terminé).

Enjoy!



Xya

Commentaire de TigerFab le 10/05/2004 16:17:42

Cooooooool ca !

Merci Xya, là comme ca c'est un génial remplaçant de Winsock pour .net !

Je vais tester chez moi (je suis au bureau là) en modifiant un peu le prg pour voir si on sait facilement envoyer des fichiers et voir si progression OK.

Commentaire de Focalizer le 17/07/2004 16:48:14

Très bonne source, génial. Merci

Commentaire de Focalizer le 19/07/2004 19:44:35

Bonjour,

J'ai ajouté le controle à mon projet, je me connecte à un serveur irc, lorsque le me "whois" sur celui ci, je suis bien connecté.

Lorsque je tente d'utiliser la méthode "Send", il me renvoit une erreur signalant que je suis déconnecté.

J'ai mit un point d'arrêt sur Sock_Closed, mais le programme ne s'arrête jamais sur ce point.

Que faire ?

Commentaire de magloui le 26/07/2004 11:02:53

Bonjour,
Tres bonne source, Pour moi qui suit un grand debutant, cela me fait progresser.
Comme deja demander, comment faire pour que le serveur accepte, plusieur connection.
Et comment faire pour que le serveur continue d'ecouter quand le client se deconnecte.

Un grand merci, pour ton tarvail, continue a nous envoyer de bonne source.

Commentaire de Oueb le 21/12/2004 10:02:07

Excelent travail !!! 10/10 manque juste le serveur multithread ... ou alors suis trop con pour trouver :)

Commentaire de Xya le 21/12/2004 13:57:59

D'abord merci pour le commentaire et la note :)
En effet il manque le serveur multithread, comme je n'ai jamais fait de serveur multithread :)
En fait j'ai fait cette source pour les programmes "de bureau", qui ne tournent pas sur un serveur, genre client mail, client FTP, chat, envoi de fichiers ...

Commentaire de yissine le 22/01/2005 21:11:18

j arrive pas a telecharger le zip c est normal?

Commentaire de Xya le 23/01/2005 14:27:01

Réessaye, pour moi ça le télécharge sans problème.

Commentaire de jeoff le 07/04/2005 10:48:58

merci beaucoup ! super boulot !

Ca m'aide pas mal pour mon projet.

Par contre je cherche un moyen de connecter plusieurs clients.

Comment puis-je modifier le code pour celà ?

Merci

Commentaire de Xya le 07/04/2005 19:15:16

Je n'ai pas du tout d'expérience en ce qui concerne les serveurs multi-clients, c'est pour ça que cette classe est prévue pour un client se connctant à un serveur (le serveur ferme la connexion en écoute dès qu'un client se connecte).

Pour connecter plusieurs clients, voilà où modifier le code:

dans AutoSocket.vb, dans la région "Evénéments"

Private Sub eventSink_Accept(ByVal sender As Object, ByVal status As Integer) Handles eventSink.Accept
        Dim newSocket As Socket = Socket.Accept()

        If closeServer Then
            _socket.Close()
        Else
            _baseServer = CloneSocket()
        End If
        _socket = newSocket
        'crée un nouveau dispatcheur: le handle du socket a changé
        ResetEventSink(_socket.Handle)
        _state = SocketState.Connected
        RaiseEvent Connected(Me, EventArgs.Empty)
    End Sub

Je pense qu'il faudrait ajouter un événement ClientConnected à AutoSocket avec comme paramètre le nouveau socket qui est connecté au client à la place de l'événement Connected.
Dans eventSink_Accept, le serveur ne fermerait pas le socket sur lequel il écoute, créerait un nouveau AutoSocket avec le Socket retourné par Accept - donc ajouter un constructeur Private qui prend comme paramètre un Socket et qui initialiserait ce socket (voir NewSocket) - ne réinitialiserait pas le dispatcheur d'événement (ResetEventSink), laisserait l'état du socket sur SocketState.Listening et lancerait l'événement ClientConnected.

Voilà, j'espère que ça pourra t'aider sur ton projet.

Commentaire de jeoff le 08/04/2005 09:11:11

ca m'a l'air un peu complexe à mettre en place vu mon niveau actuel.

Je vais commencer par me documenter sur les événements parceque je ne connais pas vb.net; juste vba pour l'instant donc forcèment je suis hyper limité sur le coté "événementiel" de la chose :/

Commentaire de dragon le 25/04/2005 18:20:05

j'ai un problème lorsque je l'appel d,un autre IP que 127.0.0.1 ???

ks.Connect(New IPEndPoint(IPAddress.Parse(addresse), Int32.Parse(port)))

je fais ça pour me connecter dont addresse = 127.0.0.1 ou mon IP

mais dès que je tombe sur _socket.Connect(remoteEP) là ça plante avec un "Aucune connexion n'a pu être établie car l'ordinateur cible l'a expressément refusée"

pourtant mon serveur est bien sur Nom: localhost et port est bien le même.

j'ai fermé tout les firewall et antivirus, donc c'est pas ça non plus

je fais les tests sur un même ordi

Commentaire de dragon le 25/04/2005 18:22:45

c'est beau j'ai trouvé, c'était le localhot du serveur qui devait être changer pour l'IP

je comprend pas trop pourquoi, puisque c'est lui le serveur, mais bon.

Commentaire de OneHacker le 14/10/2005 21:35:47

Beau travail ! Félicitations ! 10/10
Cela me servira beaucoup ! Merci !


Bonne continuation !

Commentaire de COlive le 02/01/2006 13:03:40

Très bonne source.

Je suis depuis peu sous VB 2005 et le framework 2. J'essaie en vain, de réaliser un composant similaire en utilisant les classes suivnates : TcpListener, TcpClient et BackGroundWorker.
Malheureusement, mes compétences dans le domaines des sockets (TcpListener, TcpClient étant des dérivées) sont limitées et font que je n'y arrive pas. (Héhé on peut tout savoir faire non plus.)

Ton code est très bien fait, et devrait m'en apprendre beaucoup.

Il faut continuer !!!

Commentaire de casnic le 12/01/2006 12:12:41

Très bon boulot, merci !

Ce code m'a permis de faire un bon dans l'avancement de mon projet. Par contre, l'erreur suivante se produit de temps en temps lorsque j'appelle la méthode Send de ta classe AutoSocket :

"System.InvalidOperationException : Impossible de bloquer un appel sur ce socket, pendant qu'un appel asynchrone antérieur est en cours."

Pour le moment mon application n'envoie qu'une seule trame, mais en reçois plusieurs.

Mes connaissances dans les Socket étant limitées pour l'instant, j'aimerais que tu m'aides à ce sujet.

Merci pour ton aide !

Commentaire de Xya le 13/01/2006 12:49:30

Cela fait un bout de temps que je n'ai pas mis à jour cette source, comme la version actuelle est en C# où cette erreur est corrigé !

Voilà le code à rajouter dans AutoSocket.Send:

                    Dim bytesLeft As Integer = data.Length
                    Dim sendTotalBytes As Integer = data.Length
                    Dim sendCurrentBytes As Integer = 0
                    '<==== Code à rajouter

                    'attend que le socket soit prêt, il se peut que le buffer d'envoi
                    'soit plein, ce qui lève une exception puisque le socket n'est pas bloquant
                    While !Socket.Poll(0, SelectMode.Write)
                        System.Threading.Thread.Sleep(0)
                    End While
                    '       Code à rajouter ====>

                    While bytesLeft > 0

Commentaire de Xya le 13/01/2006 12:51:05

Une petite correction, dans la ligne While ... Socket.Poll, il faut remplacer '!' par 'Not ', petite erreur de conversion VB.NET de ma part :)

Commentaire de casnic le 16/01/2006 09:36:32

Merci, ça fonctionne nickel !!!

par contre j'ai du placer cette boucle dans la boucle suivante. Sinon l'erreur se produisait encore de temps en temps.

Merci pour ton aide précieuse !

Commentaire de casnic le 17/01/2006 08:21:19

Enfin de compte l'erreur se produit encore même si beaucoup plus rarement.

Aurais-tu une idée ?

Merci encore ...

Commentaire de Sebounet69 le 01/02/2006 17:09:22

Je dois faire un chat en VB et je désire utiliser les sockets... Il faut que kje le fasse le plus rapidement possible... Est ce que le code est bien commenté histoire que je comprenne comment ça marche et comment on l'utilise... Et est-ce que vous connaissez des adresses qui explique correctement les sockets.

Merci d'avance

Salutations

Commentaire de OneHacker le 19/02/2006 23:42:45

J'arrive pas à avoir la bonne FrameWork 2.0 moi j'ai la FrameWork 2.0 Bêta et ca marche pas.

Redman

Commentaire de psycho81 le 16/03/2006 08:14:50

Bonjour,

Je vous explique mon problème. Je souhaite faire un peer2peer privé. Donc arriver à joindre directement une personne sur internet via son ip pour lu itransmettre des paquets. jusque la, rien de bien difficile. Si bien sur les 2 clients sont les passerelles internet.

Supposons maintenant un reseau X1 ou il y a les ordinateur A1, B1 et C1 et A1 est la passerelle.

Supposons aussi un reseau X2 ou il y a les ordinateur A2, B2 et C2 et A2 est la passerelle.

Comment faire pour que C2 puisse directement communiquer avec C (ou B1) sans faire de serveur sur A1 ou A2.

Car mon application marche que de passerelle à passerelle. J'ai essayé le multicast par desespoir mais celà ne apsse pas dans Internet.

Si vous pouviez m'aiguiller dans mon problème par un bout de code .... j'en serai plus que ravi !

Bernard

Commentaire de kamikazlolo le 11/07/2006 19:09:15

Marche tres bien pour le TCP, mais tu as testé pour l'UDP ?
Dans tous les cas TCP ou UDP, tu l'instancie la socket avec cette commande :
_socket = New Socket(af, SocketType.Stream, prot)

SocketType.Stream pour de l'UDP -> plantage

Mais sinon vraiment tres pratique comme appli, bravo ;)

Commentaire de VPNVB le 08/09/2007 14:23:43

Salut

C'est un Source tré tré util
merci pour la Class !

Je souaite développer un Serveur SMTP, IMAP et POP3
S'a peux M'aider ?

Merci de Me Contacter par Email ou Directe...

Commentaire de FLLM le 08/09/2007 23:28:54

J'ai pas testé mais l'idée est génial et rien que pour sa tu mérite un 10 !

Merci bcp sa va me débloquer dans un de mes projets !!

Commentaire de terbeh le 26/02/2008 17:28:04

Bonjour, je suis débutant et ton code m'intéresse vraiment. Par contre je n'arrive pas à démarrer le serveur. Il reste toujours en état "Déconnecté". Je souhaite que tu m'aide avec un peu plus de commentaire dans le code.

Merci

Commentaire de Mayzz le 28/04/2009 23:18:17

Une petite erreur à la connexion...

Opération inter-threads non valide : le contrôle 'txtClientInput' a fait l'objet
d'un accès à partir d'un thread autre
que celui sur lequel il a été créé.

Suis-je le seul à qui cette erreur est survenue ?

Commentaire de Xya le 29/04/2009 00:24:36

Si je me souviens bien (j'ai écrit ce code y'a 5 ans quand même :p et pas le courage de le télécharger et de le regarder), le socket doit utiliser un thread d'arrière plan pour gérer les différents événements.

Le problème, c'est que tout les contrôle windows forms (namespace System.Windows.Forms.*) doivent être impérativement utilisés sur le thread principal (c'est à dire tout code qui accède à leur méthodes et propriétés). Il n'y avait aucune vérification dans le Framework 1.1, par contre je crois que c'est à partir du 2.0 que cette "règle est vérifiée", et si elle n'est pas respectée, tu obtiens l'exception que tu as copié-collé.

La solution la plus rapide, c'est d'appeller BeginInvoke/Invoke dans tous les événements du socket, de sorte à exécuter le code qui accède à Windows Forms dans le thread principal. Exemple:

Private Sub socket_DataArrival( sender As Object, data As Byte() )
    Me.BeginInvoke(ma_fonction_windows_forms, New Object[] {data}) ' synatxe VB?
End Sub

Private Sub ma_fonction_windows_forms(data As Byte())
    txtClientInput.Text = Encoding.UTF8.GetString(data)
End Sub

Ca fait des années que j'ai pas fait de VB.NET (et pas de compilateur sous la main), donc je me souviens plus de la syntaxe, surtout pour la création de tableau et le passage du délégué (voir commentaire).
L'idée c'est tu passe un délégué de ta fonction (ici ma_fonction_windows_forms) comme 1er paramètre, et un tableau contenant la liste des paramètres de ta fonction comme 2ième paramètre. Ca c'est la solution rapide, bête et méchante, et pas hyper propre.

La solution plus "clean" serait de rajouter une propriété SynchronizingObject (de type ISrynchronizeInvoke -- interface implémentée par tous les contrôles Windows Forms) à la classe de Socket. Ensuite tu dois utiliser la méthode BeginInvoke de ton objet SynchronizingObject pour déclencher les événements.

Je pense qu'avec ça tu dois avoir pas mal de pistes pour régler le problème (je pense que tu devrais trouver sur le net le code pour utiliser BeginInvoke/Invoke et les événements VB.NET). J'espère que ça t'aidera!

Greetings from Norway
Xya

Commentaire de Mayzz le 29/04/2009 08:20:59

Merci pour ces commentaires détaillés ;)
J'ai pu trouver quelques explications en faisant des recherches hier,

Par contre... c'est bizard car quand je démarre le programme compilé ça fonctionne ?
l'exception n'est pas prise en compte ???

Commentaire de Xya le 29/04/2009 08:29:19

Pt'être que pour des raisons de performances cette règle n'est vérifiée que quand tu lance ton programme dans un débogueur comme Visual Studio? De toute qu'elle soit vérifiée ou pas vaut mieux la suivre, ssurtout pour une appli réseau. Je me souviens avoir eu des bugs vraiment bizarre/aléatoires quand je le faisais pas

Commentaire de Mayzz le 29/04/2009 11:48:39

je pense que tu as entièrement raison d'ailleurs aurais-tu une idée ou une ressource pour implémenter ISynchronizeInvoke ?

Je suis en train de faire une classe de dialogue TCP avec un protocole intégré et des fonctions qui utilise les sockets.
Cette classe permettra entre autre de gérer les connexions Client/serveur, l'envoi de message simplifié avec paramètres et gèrera directement l'envoi de fichier avec événements (Start, Finish, Progress...).

J'aimerais pourvoir faire des événements (un peut comme dans ta classe), en ce qui concerne les sockets sans avoir à chaque fois à appeler BeginInvoke/Invoke... :/

J'ai recherché partout mais j'ai pas trouvé grand chose, de plus je ne suis pas un expert en ce qui concerne le multithreading.

ET Merci pour ta disponibilité :p

Commentaire de Xya le 29/04/2009 12:44:02

L'idé c'est de rajouter une propriété à la classe:

Protected syncObj As ISynchronizeInvoke           'objet de synchronisation Windows Forms

    Public Property SynchronizingObject() As ISynchronizeInvoke
        Get
            Return syncObj
        End Get
        Set(ByVal Value As ISynchronizeInvoke)
            syncObj = Value
        End Set
    End Property

Pour chaque événment tu dois ajouter une méthode OnXXX qui détermine si on doit utiliser BeginInvoke ou pas:

    Public Event Disconnected(ByVal sender As Object, ByVal e As EventArgs)

    Protected Overridable Sub OnDisconnected(ByVal e As EventArgs)
        If Not syncObj Is Nothing AndAlso syncObj.InvokeRequired Then
            Dim deleg As New EventHandler(AddressOf SyncDisconnected)
            syncObj.BeginInvoke(deleg, New Object() {Me, e})
        Else
            SyncDisconnected(sender, e)
        End If
    End Sub

Et une øéthode SyncXXX qui déclenche juste l'événement:

    Protected Sub SyncDisconnected(ByVal sender As Object, ByVal e As EventArgs)
        RaiseEvent Disconnected(sender, e)
    End Sub

La version VB.NET est un peu lourde, comme je pense pas qu'on puisse récupérer le délégué de l'événement contrairement à C#, sinon on pourrait faire (dans OnXXX):

syncObj.BeginInvoke(Me._delegue_Disconnected, New Object() {Me, e})

et se passer de SyncXXX.

Pas de soucis :p J'espère que ca te øettra sur la voie.

Commentaire de Mayzz le 29/04/2009 12:57:05

Hééé ! Bien vu !
Je vais tester ca de suite, encore Merci ;)

Commentaire de Mayzz le 29/04/2009 13:18:53

Heuu... au fait, qu'est ce qui défini la valeur de "syncObj" c'est tout la le problème ?
Car si on gère le code normalement au niveau du formulaire on n'a qu'a faire :

Private sub Control_Disconnect (sender as Object, e as System.EventArgs) Handles Control.Disconnect
    'Je veu par exemple afficher "déconnecté" dans un label
    If (Label.InvokeRequired) Then
        Label.Invoke(New DelegSub(AddressOf e_Connexion), Sender, e)
    Else
        Label.Text = "Déconnecté"
    End If
End sub

Et la on obtient l'état de l'objet de synchronisation du label, mais dans le cas ou le code est géré par ma classe comment transmettre ce paramètre à "syncObj" ???

Commentaire de Xya le 29/04/2009 14:27:59

Tu peux utiliser n'importe quel contrôle comme SynchronizingObject.

Par exemple imaginons que tu crées le socket dans le constructeur de ta form:

Public Sub New()
   '...
   Me.socket = New AutoSocket()
   Me.socket.SynchronizingObject = Me
End Sub

et après dans tes gestionnaires d'événements t'as plus à te soucier de Invoke/BeginInvoke (cad les événements sont automatiquement exécut´s dans le thread principal):

Private sub Control_Disconnect (sender as Object, e as System.EventArgs) Handles Control.Disconnect
    'Je veu par exemple afficher "déconnecté" dans un label
     label.Text = "Déconnecté"
End sub

Commentaire de Mayzz le 29/04/2009 14:36:05

Ok, ok !

Merci bien pour toutes ces informations heureusement qu'il y a encore des gens pour partager leur savoir et filer un coup de main sans attendre des choses en retour :) (ce qui fait que le développement évolu plus vite que certaine personnes ou choses de la vie...)

Merci encore @+

Commentaire de Xya le 29/04/2009 14:57:10

Pas de soucis :)

Ce qui m'étonne un peu c'est que ce bout de code soit toujours utile et utilisé, même 5 ans après que je l'ai écrit !

A+

Xya

Commentaire de Mayzz le 29/04/2009 15:21:13

Hi, ben en fait j'ai laissé de coté .Net durant quelque années je m'obstinai à vouloir resté sur vb6 mais arrive un moment ou on est bien obligé de suivre...

Bref je m'y suis mi et je ne le regrette pas, mais je regrette for mon Mswinsck.ocx... ce bon vieux winsock était si facile d'utilisation...
Je trouve franchement la classe system.Net.Socket très mal faite, j'ai même trouvé des exemple de code socket avec des fonctions non synchrones et des timers !

En ce qui concerne ton code il sera toujours utile jusqu'à modification par MS de System.Net.Socket...

Commentaire de Xya le 29/04/2009 18:28:53

C'est vrai que les classes de Socket de .NET sont pas pratiques à utiliser avec Windows Forms, parce qu'elle ont été pensées pour être utilisée dans une partie client ou serveur de l'application, et non pas mélangée à la présentation (Forms).

Donc d'un côté c'est moins pratique, mais ça force à bien réfléchir à l'architecture de l'application, le flux de données, les threads, etc. Perso c'est quelque chose que j'adore et que je trouve hyper intéressant, mais ça demande pas mal de temps et de recherches.

Par exemple c'est pas une bonne chose d'appeler des fonctions blocantes (synchrones) sur le thread de l'interface graphique, puisque ça fait freezer l'affichage de tes fenêtres. C'est pour ça que le plus simple c'est d'avoir un thread dédié à ton socket. L'alternative c'est d'utiliser les fonctions asynchrones ou des événements mais c'est plus difficile à bien structurer, enfin c'est mon point de vue.

Commentaire de Xiu le 21/07/2009 12:42:33

Salut,
Comment mettre dans une variable les données d'un socket precis ?
merci

Commentaire de Kardyne le 31/08/2009 11:38:32

Bonjour,
Premièrement, je tiens à dire que ce code est vraiment super !
Ensuite, j'ai un petit problème avec les évènements DataDeparture et SendComplete. L'évènement ne se déclenche pas.
J'ai cherché dans le code de la classe d'où pourrait venir l'erreur, mais sans succès.
Voila, voila...

Merci d'avance.

Kardyne.

Commentaire de Xya le 31/08/2009 14:34:18

Bonjour,

Merci! Et c'est marrant parce qu'en ce moment je suis aussi en train de bosser avec des sockets, mais non bloquants (sous Linux) et avec Python.

Pour être honnête ça fait des années que j'ai pas touché au code et que j'ai pas programmé en VB.NET donc je suis pas sûr d'être d'une grande aide pour trouver le bug.

Mais pour essayer, est ce que les données sont bien envoyées? Est ce que si tu mets un point d'arrêt sur '_socket.Send(data, ...)' dans AutoSocket.Send() il passe dessus? Et sur la ligne 'RaiseEvent DataDeparture' ?

Commentaire de hussein47 le 02/09/2009 21:40:11

Y aurai 'il moyen d'utiliser ta classe en mode console, tu peut me montrer un exemple sil te plait, je suis débutant...

Commentaire de Xya le 02/09/2009 21:50:48

Je pense pas qu'elle soit très adaptée au mode console, le plus simple serait d'utiliser les classes Socket, TcpServer ou TcpClient du framework. Qu'est ce que tu veux faire en gros?

 Ajouter un commentaire




Nos sponsors


Sondage...

CalendriCode

Septembre 2010
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
27282930   

Consulter la suite du CalendriCode

 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 0,546 sec (4)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales