[plusieurs Problème] - programmation réseau VB.net
Bonjour à tous je dois concevoir une appli réseau qui utilise le protocole UDP en VB.net. donc je décide de développer des procédures stocké dans un module dédié afin de les séparer de mon code et je vous référence mes problème
Pour commencer dans le module nommé "Communication.vb" j'ai trouvé sur internet une fonction qui retourne l'adresse MAC d'une IP donné
Code:
1 2 3 4 5 6 7 8 9 10
|
Declare Function SendARP Lib "iphlpapi.dll" (ByVal DestIP As UInt32, ByVal SrcIP As UInt32, ByVal pMacAddr As Byte(), ByRef PhyAddrLen As Integer) As Integer
Function GetMAC(ByVal IPAddress As String) As String
Dim addr As Net.IPAddress = Net.IPAddress.Parse(IPAddress)
Dim mac() As Byte = New Byte(6) {}
Dim len As Integer = mac.Length
SendARP(CUInt(addr.Address), 0, mac, len)
Dim macAddress As String = BitConverter.ToString(mac, 0, len)
Return macAddress
End Function |
à la ligne SendARP(CUInt(addr.Address), 0, mac, len) j'ai la variable "addr.address" souligné en vert avec le message d'avertissement suivant :
'Public Property Address As Long' est obsolète*: 'This property has been deprecated. It is address family dependent. Please use IPAddress.Equals method to perform comparisons. cependant la fonction ... fonctionne : je cherche à virer cet avertissement :)
ensuite voilà le plus gros problème que j'ai : j'ai vu que pour la réception d'un message qu'il faut créer un background-worker afin d'éviter de geler le programme et je dois avouer que c'est bien compliqué ><'
je vous colle ici le code de mes procédure d'écoute :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
|
Dim ecouter_local_port As Integer
Dim ecouter_hote_ip_distant As IPAddress
Dim ecouter_hote_port_distant As Integer
'UDP recevoir message
'on déclare un nouveau background_worker avec event
Private WithEvents Ecouter As System.ComponentModel.BackgroundWorker
Sub udp_recevoir_message(ByVal autre_form_local_port As Integer, ByVal autre_form_ip_hote_distant As String, ByVal autre_form_port_hote_distant As Integer)
'on crée le thread d'écoute
Ecouter = New System.ComponentModel.BackgroundWorker
' on configure le thread
Ecouter.WorkerReportsProgress = True
Ecouter.WorkerSupportsCancellation = True
'on configure les Handler pour ce thread dont on a besoin
AddHandler Ecouter.DoWork, AddressOf Ecouter_DoWork
AddHandler Ecouter.RunWorkerCompleted, AddressOf Ecouter_RunWorkerCompleted
'depuis l'autre form on récupère les valeurs demandé (le port d'écoute local, les IP sources et les ports sources)
ecouter_local_port = autre_form_local_port
'récupération du port local en vue de la création du socket local (qui sont en variable globale)
ecouter_hote_port_distant = autre_form_port_hote_distant
'récupération du remote port depuis autre_form vers variable locale
' test de la variable IP_distant = any (on accepte les données de tout les hote ou seulement une IP en particulier ?)
If autre_form_ip_hote_distant = "any" Then
'commande si autre_form_ip_hote_distant = "any"
ecouter_hote_ip_distant = IPAddress.Any
Else 'sinon
' commande si autre_form_ip_hote_distant != "any"
ecouter_hote_ip_distant = IPAddress.Parse(autre_form_ip_hote_distant)
End If 'fin de test
'On lance l'écoute (rappel : les variables désignant le port d'écoute local, les IP sources et les ports sources sont globalisé)
Ecouter.RunWorkerAsync()
End Sub
Sub Ecouter_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles Ecouter.DoWork
'On déclare une connexion UDP
Dim receivingUdpClient As New UdpClient(ecouter_local_port)
'On désigne un hote distant
Dim RemoteIP As New System.Net.IPEndPoint(ecouter_hote_ip_distant, ecouter_hote_port_distant)
'On lance la réceptions des donnée
Dim receiveBytes As [Byte]() = receivingUdpClient.Receive(RemoteIP)
'on convertis les données recu
Dim returnData As String = Encoding.ASCII.GetString(receiveBytes)
'on prépare l'expédition du résultat au process principal
e.Result = returnData
'on ferme la connexion UDP
receivingUdpClient.Close()
'on stop le thread secondaire tout en renvoyant le résultat au sub Ecouter_RunWorkerCompleted via le handler qui va bien
System.Threading.Thread.Sleep(1)
End Sub
Private Sub Ecouter_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles Ecouter.RunWorkerCompleted
'On récupère la chaine transmise lors de la cloture du background worker
Dim recup_data As String = e.Result
'on déclenche une fonction de traitement
traiter_message_recu(recup_data)
End Sub
Sub traiter_message_recu(ByVal message_a_traiter As String)
'On fait le traitement
Form1.Label1.Text = message_a_traiter
'je dois redéclencher l'écoute de facon automatique ici
udp_recevoir_message(10000, "any", 0)
End Sub |
l'appel de l'écoute depuis form1 :
Code:
1 2 3 4 5
|
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
Communication.udp_recevoir_message(10000, "any", 0)
Label1.Text = "En attente de reception"
End Sub |
j'ai plusieurs problème :
le 1er est que lorsque l'écoute est active il ne récupère que le second paquet UDP reçu exemple
lancer écoute coté serveur (label1 = "en attente de réception")
client envoie message "salut"
client envoie message "toto"
Serveur traite "toto" (label1 = "toto")
ensuite si je demande une écoute secondaire (en recliquant sur le bouton1) après réception d'un message cela redémarre l'écoute.
si je demande à automatiser l'écoute (par exemple en rappelant la sub depuis traiter_message_recu) je lève une exception de socket déjà utilisé oO alors que j'ai bien demandé la cloture du socket une fois le message reçu via la ligne "receivingUdpClient.Close()" . Je me rappelle des cours de VB ou mon profs nous expliquait que l'on pouvais forcer la libération des ressources mais j'y arrive pas :(
Pouvez vous m'aider ?
Merci d'avance :)