Socket TCP [Résolu]

Signaler
Messages postés
135
Date d'inscription
dimanche 19 novembre 2000
Statut
Membre
Dernière intervention
2 décembre 2011
-
Messages postés
14008
Date d'inscription
samedi 29 décembre 2001
Statut
Modérateur
Dernière intervention
28 août 2015
-
<dir>

Bonjour a tous

Ce source socket TCP tiré des codes de vbfrance (merci aux auteurs au passage) regroupe un client et un serveur !


J'ai essayé de simplifier, mais sans succès !


Je suis sûr qu'il y a moyen de simplifier et d'alléger tout ça !
 
Un peu d'aide SVP ?

Source Vb.rar ICI



</dir>

11 réponses

Messages postés
14008
Date d'inscription
samedi 29 décembre 2001
Statut
Modérateur
Dernière intervention
28 août 2015
68
Re
Oui, car ce genre de gestion peut devenir compliqué.
Pour la troisième fois, je te conseille de lire des sources qui parlent de Chat et qui utilisent ce genre de séparateurs qu'il est indispensable d'utiliser si tu veux isoler facilement les messages, car quand tu auras plusieurs utilisateurs, les données vont se succeder dans le DataArrival.

Pour tout te macher, lors de lémission d'un message, il te suffit d'ajouter un caractère (borne) facile à repérer et qu'on ne risque pas de trouver dans les données échangés. J'ai personnellement choisi Chr$(0) pour séparer les données à l'intérieur d'un même message et Chr$(1) pour désigner la fin du message. Exemple
   monWinsock.SendData "Le 1er texte" & Chr$(0) & " que je veux envoyer" & Chr$(1)
Par exemple, si tu dois envoyer le contenu d'uhne ListBox, il te suffira de faire une boucle :
   Dim PrépareTexte As String
   For r = 1 to maListBox.ListItem.Count
      PrépareTexte = PrépareTexte & Chr(0) & maListBox.ListItem(r)
   Next r
   monWinsock.SendData PrépareTexte & Chr$(1)
A la réception, je ne commence à traiter les messages (donc il faudra les mémoriser) que lorsque je suis sur d'avoir un Chr$(1) dedans (un Instr suffit). Ensuite, j'isole les données internes du message en faisant un Split avec le séparateur Chr$(0).
Il te faut donc gérer :
- Le stockage des données entre deux déclenchements d'un DataArrival. Ce stockage doit être un tableau indexé si tu as à faire à plusieurs clients (un stockage par client).
- La détection d'une borne finale Chr(1).
- Si tu l'as trouvée, tu prends ce qu'il y a devant et tu gardes ce qu'il peut éventuellement y avoir derrière pour un prochain traitement.
- Un Split avec Chr(0) pour isoler chaque terme du message.

Vala
Jack, MVP VB
NB : Je ne répondrai pas aux messages privés

<hr />Le savoir est la seule matière qui s'accroit quand on la partage (Socrate)
Messages postés
14008
Date d'inscription
samedi 29 décembre 2001
Statut
Modérateur
Dernière intervention
28 août 2015
68
Salut
lol, il n'y a pas de lien entre les sources déposées et le forum.
On ne sait donc pas de quoi tu parles.
De toute façon, je pense qu'il serait préférable de poser tes questions sur un commentaires lié à la source, si elle ne fonctionne pas bien : l'auteur sera surement plus qualifié pour répondre rapidement.

Vala
Jack, MVP VB
NB : Je ne répondrai pas aux messages privés

<hr />Le savoir est la seule matière qui s'accroit quand on la partage (Socrate)
Messages postés
135
Date d'inscription
dimanche 19 novembre 2000
Statut
Membre
Dernière intervention
2 décembre 2011

Dsl pour l'erreur dans le lien
 Source ICI
Messages postés
135
Date d'inscription
dimanche 19 novembre 2000
Statut
Membre
Dernière intervention
2 décembre 2011

Bonjour Jack

Ce source fonctionne très bien je cherche seulement à l’optimiser et a l’alléger au maximum avant de l’intégrer a mon projet!

Cordialement

Léo
Messages postés
135
Date d'inscription
dimanche 19 novembre 2000
Statut
Membre
Dernière intervention
2 décembre 2011

voila le code:

 Form Client

Option Explicit


'Pour placer le texte du bouton "go" et dire si on peut envoyer du stock
Private Sub CheckState_Timer()If Socket.State 7 Then Go.Caption "Se déconnecter": send.Enabled = True: Exit Sub Else: send.Enabled = False
'On est connecté donc on peut envoyer du texte et le texte du bouton doit être "se déconnecter"If Socket.State 0 Then Go.Caption "Se connecter": Exit Sub
'On n'est pas connecté donc on ne peux pas envoyer du texte et le texte du bouton doit être "se connecter"
Go.Caption = "Annuler"
'On peut annuller
End Sub


Private Sub Form_Load()
'On démarre tout de suite le timer
CheckState_Timer
End Sub


Private Sub Go_Click()
'Si on est pas connecté
If Socket.State <> 7 Then
    If Socket.State = 0 Then
    'On ferme le socket (si il est pas fermé...)
    Socket.Close
    'On se connecte à l'adresse voulue sur le port voulu
    Socket.Connect addr.Text, port.Text
    Else
    'Fermeture du socket
    Socket.Close
    End If
'Le timer fait une vérification
CheckState_Timer
Else
'On fait juste fermer alors
Socket.Close
CheckState_Timer
End If
End Sub


'Envoie des données et on les affiche dans notre console
Private Sub send_Click()If Socket.State 7 Then recep.Text recep.Text & "<Client> : " & vbCrLf & Emission.Text & vbCrLf & vbCrLf: Socket.SendData Emission.Text: Emission.Text = ""
End Sub


'La connexion est finie (on le dit)
Private Sub Socket_Close()
recep.Text = recep.Text & recep.Text & "<system> : Connexion terminée!" & vbCrLf & vbCrLf
send.Enabled = False
End Sub


'On vient de se connecter (on le dit)
Private Sub Socket_Connect()
recep.Text = recep.Text & recep.Text & "<system> : Connexion établie avec " & Socket.RemoteHostIP & " !" & vbCrLf & vbCrLf
send.Enabled = True
End Sub


'Les données arrivent
Private Sub Socket_DataArrival(ByVal bytesTotal As Long)
Dim data As String
'On les met dans la variable data
Socket.GetData data, vbString
'On les affiche
recep.Text = recep.Text & "<" & Socket.RemoteHostIP & "> : " & vbCrLf & data & vbCrLf & vbCrLf
End Sub


Private Sub Socket_Error(ByVal Number As Integer, Description As String, ByVal Scode As Long, ByVal Source As String, ByVal HelpFile As String, ByVal HelpContext As Long, CancelDisplay As Boolean)
'ERREUR!!! ON AFFICHE L'ERRREUR ET ON FERME LE SOCKET
MsgBox "Erreur avec le socket! & vbcrlf # " & Number & vbCrLf & Description
Socket.Close
End Sub

Form Serveur

Option Explicit


Dim i As Integer


Private Sub CheckState_Timer()
'Si il n'y a pas de client, pourquoi envoyer un message?If Clients.ListCount 0 Then send.Enabled False Else: send.Enabled = True
'Placer le texte du bouton GoIf Ecoute.State 0 Then Go.Caption "Écouter" Else: Go.Caption = "Arrêter le serveur"
End Sub


Private Sub Clients_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
'Si on clique avec le bouton droit et qu'on a sélectionner un ip dans la liste, on affiche le menu
If Button = vbRightButton And Clients.ListIndex <> -1 Then
PopupMenu pop
End If
End Sub


'ON LE BOOT!!
Private Sub Decon_Click()
Dim col
'On récuprère son # de socket (après le ":")
col = Split(Clients.List(Clients.ListIndex), ":")
'On fait comme s'il aurait quitté
Socket_Close (CInt(col(1)))
End Sub


'Demande de connexion
Private Sub Ecoute_ConnectionRequest(ByVal requestID As Long)
Dim Nb As Integer
'# de la prochaince socket disponible (LIMITE : 65535 CAR TYPE INTEGER = SUR 4 OCTETS (FFFF))
Nb = Socket.Count
'On charge ce socket
Load Socket(Nb)
'On fait accepter la connexion
Socket(Nb).Accept requestID
'On dit que le client c'est connecté
recep.Text = recep.Text & recep.Text & "<system> : Connexion établie avec " & Socket(Nb).RemoteHostIP & " !" & vbCrLf & vbCrLf
'On met son IP suivit de ":" et son 1 de socket dans la liste
Clients.AddItem Socket(Nb).RemoteHostIP & ":" & Nb
End Sub


'Erreur!
Private Sub Ecoute_Error(ByVal Number As Integer, Description As String, ByVal Scode As Long, ByVal Source As String, ByVal HelpFile As String, ByVal HelpContext As Long, CancelDisplay As Boolean)
MsgBox "Erreur avec le socket! & vbcrlf # " & Number & vbCrLf & Description
Ecoute.Close
End Sub


Private Sub Form_Load()
'On fait faire une première vérification avec le timer
CheckState_Timer
End Sub


'On appuie sur le bouton Go
Private Sub Go_Click()
On Error Resume Next
'Si on écoutait, ben on ferme
If Ecoute.State = 2 Then
Ecoute.Close
'On décharge tout les sockets
For i = 1 To Socket.Count - 1
Socket(i).Close
'On détruit l'objet créer (0 ne peut pas être unloadé)
Unload Socket(i)
Next
'Sinon ben on écoute le port
Else
Ecoute.LocalPort = Port.Text
'On écoute
Ecoute.Listen
'ERREUR, POURQUOI ON PEUT PAS ÉCOUTER (sûrement que le port est occupé)
If Err.Number <> 0 Then
'On dit pourquoi
MsgBox "Erreur avec le socket! & vbcrlf # " & Err.Number & vbCrLf & Err.Description
'On nettoie l'erreur
Err.Clear
End If
End If
End Sub


'Envoie du message, comme avec le client
Private Sub send_Click()
recep.Text = recep.Text & "<Serveur> : " & vbCrLf & Emission.Text & vbCrLf & vbCrLf
For i = 1 To Socket.Count - 1
Socket(i).SendData Emission.Text
Next
Emission.Text = ""
End Sub


'Le client vient de quitter ou il s'est fait booter
Private Sub Socket_Close(Index As Integer)
Dim col
'On cherche son # de socket pour l'enlever de la liste
For i = 0 To Clients.ListCount - 1
col = Split(Clients.List(i), ":")
If col(1) = Index Then
Socket(col(1)).Close
'On kill le socket
Unload Socket(col(1))
'On dit qu'il quitte
recep.Text = recep.Text & recep.Text & "<system> : Connexion terminée avec " & col(0) & " !" & vbCrLf & vbCrLf
'On l'enlève de la liste
Clients.RemoveItem i
'Pas besoins de continuer
Exit For
End If
Next
End Sub


'Arrivée des données, comme avec le client
Private Sub Socket_DataArrival(Index As Integer, ByVal bytesTotal As Long)
Dim data As String
Socket(Index).GetData data, vbString
recep.Text = recep.Text & "<" & Socket(Index).RemoteHostIP & "> : " & vbCrLf & data & vbCrLf & vbCrLf
End Sub
 
Module

Option Explicit


Private Sub Main()
Client.Show
Serveur.Show
End Sub

Ce source utilise MSWINSCK.OCX
Messages postés
14008
Date d'inscription
samedi 29 décembre 2001
Statut
Modérateur
Dernière intervention
28 août 2015
68
Re
Mais tu veux alléger quoi, je ne comprends pas bien.
Tout ceci semble être un minimum technique.
Essaye de voir et comprendre le fonctionnement puis tu verras ce que tu veux supprimer.
Reviens avec des questions précises, parce que là, difficile de te répondre ...

Vala
Jack, MVP VB
NB : Je ne répondrai pas aux messages privés

<hr />Le savoir est la seule matière qui s'accroit quand on la partage (Socrate)
Messages postés
135
Date d'inscription
dimanche 19 novembre 2000
Statut
Membre
Dernière intervention
2 décembre 2011

 je pensais uiliser un select case pour clarifier le code mais mes tentatives ne porte pas leurs fruits  je sais que j'ai encore beaucoup a apprendre sur la structure et l'optimisation!
Messages postés
14008
Date d'inscription
samedi 29 décembre 2001
Statut
Modérateur
Dernière intervention
28 août 2015
68
Re
"un select case"  Oui, c'est surement très bien, mais pour faire quoi, mystère ...
Je pense que tu parles de trier les données qui arrivent dans le DataArrival ? (Boule de Cristal 2.0)
Essaye de charger quelques codes qui parlent de "Chat" et tu verras comment le problème se traite.
Un simple Select Case ne suffit pas, il faut ajouter des bornes de séparation entre tes textes (à l'émission) afin de pouvoir faire un découpage de ces messages à la réception, sinon les données seront les unes derrière les autres ...
Ce problème est très souvent d'actualité dans les questions du forum : en cherchant un peu, tu y trouveras les réponses comme celles-ci :
http://www.vbfrance.com/infomsg_QUESTION-SUR-WINSOCK_904939.aspx
http://www.vbfrance.com/infomsg_CONNECTION-DIFFERENTES-ACTIONS-DANS-BDD-ACCESS-WINSOCK_995486.aspx

Vala
Jack, MVP VB
NB : Je ne répondrai pas aux messages privés

<hr />Le savoir est la seule matière qui s'accroit quand on la partage (Socrate)
Messages postés
135
Date d'inscription
dimanche 19 novembre 2000
Statut
Membre
Dernière intervention
2 décembre 2011

Merci Jack, Désolé de pas avoir été assez claire dans ma requête !


Tu a tous a fait cerné ce a quoi je faisais allusion !


Je n’avais pas pensé aux bornes de séparation !<?xml:namespace prefix o ns "urn:schemas-microsoft-com:office:office" /??>



C’est pour cela que mon appli s’emballait à la réception des paquets !





Je m’aperçois que cette modification est plus compliquée que je ne l’avais imaginée !





Cette modification a-t-elle un impacte significatif sur le programme en lui même ?
Messages postés
135
Date d'inscription
dimanche 19 novembre 2000
Statut
Membre
Dernière intervention
2 décembre 2011

Merci Jack
Messages postés
14008
Date d'inscription
samedi 29 décembre 2001
Statut
Modérateur
Dernière intervention
28 août 2015
68
 de rien