2017-08-25 9 views
0

En ce moment je développe un outil qui me permettra de mesurer le délai entre les connexions réseau utilisant VB6 et un arduino UNO avec blindage ethernet. Maintenant, je suis confronté à des problèmes avec le code du serveur (le programme VB6). J'ai 2 winches avec les deux ports différents et ils écoutent tous les deux le client arduino pour se connecter. Maintenant, si je n'ai qu'une seule connexion active, rien ne va mal et tout fonctionne bien, mais dès que le deuxième client se connecte, tout le serveur commence à devenir fou. Soudain, il signale que le premier client connecté a perdu la connexion, donc en bref, le serveur ne veut tout simplement pas 2 clients connectés à la fois mais j'en ai vraiment besoin:/Qu'est-ce qui ne va pas?VB6 serveur winsock et plusieurs clients arduino numéro

Je vais vous expliquer rapidement quelles sont les commandes Sertain qui sont envoyées sur le serveur via le serveur Winsock.

"SERVER_SLEEP" Is a command that the server sends to all clients that will tell them to enter a power saving mode. "SERVER_REQUESTS_DATA" Is a command that the server sends to a specific client and forces the client to send information like Device name and firmware version. "RESPOND_MESSAGE" Is a command that the server sends to all clients and the client is forced to respond to see if we still have an connection. "DEVICE_NAME=" Is a command that the client sends to the server when it just connects, It is required before we show that we have an connection by putting it into the listbox. (after the = comes the device name) "DEVICE_NAME_REP=" Is a command that the client sends to the server when the server requests information about the client, the reason i have 2 of them is because i couldn't reuse the previous one since then it would become way to complicated. (after the = comes the device name) "DEVICE_FIRMWARE=" Is a command that the client sends to the server when the server requests information about the client. (after the = comes the device firmware version) "DEVICE_OK=" Is a command that the client sends to the server when the server requests an answer to check if we still have an connection. (after the = comes the device name) "DEVICE_REBOOTING" Is a command that the client sends to the server when it goes out of sleep mode (it goes out of that mode when the server comes back online again after it was closed) After the client send that message it immediately closes the connection again and the device is forced to reboot to make sure nothing goes wrong.

Mon code:

Dim DeviceIP1 As String 
Dim DeviceIP2 As String 
Dim UpdateListStatus As Integer 

Private Sub Command1_Click() 
MsgBox Socket1.State 
MsgBox Socket2.State 
End Sub 

Private Sub Command3_Click() 
If Dir(App.Path & "\TH.exe") <> "" Then 'Traceroute Helper application i wrote before, Works 100% and is not relevant for the issue i am facing 
Shell App.Path & "\TH.exe " & DeviceIP, vbNormalFocus 
Else 
MsgBox "Missing file!" & vbNewLine & "File TH.exe is required for the requested operation!", vbCritical + vbSystemModal, "Missing file" 
End If 
End Sub 

Private Sub Form_Load() 
Socket1.Listen 
Socket2.Listen 
End Sub 

Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer) 
Dim msg As VbMsgBoxResult 
msg = MsgBox("Are you sure you want to exit?" & vbNewLine & "All the clients will be put into sleep mode.", vbYesNo + vbQuestion + vbSystemModal, "Quit") 
If msg = vbYes Then 
    Form3.Show 
    Cancel = True 
    Form1.Visible = False 
Else 
    Cancel = True 
End If 
End Sub 

Private Sub List1_Click() 
On Error GoTo errhandler 
Dim ClientFound As Boolean 
DeviceIP = Mid(List1.Text, InStr(List1.Text, "-") + 1) 
DeviceIP = LTrim(DeviceIP) 
DeviceIPLabel.Caption = "Device IP: " & DeviceIP 
Form2.Show 
    If Socket1.RemoteHostIP = DeviceIP Then 
    Socket1.SendData ("SERVER_REQUESTS_DATA") 
    ElseIf Socket2.RemoteHostIP = DeviceIP Then 
    Socket2.SendData ("SERVER_REQUESTS_DATA") 
    End If 
Exit Sub 
errhandler: 
If Err.Number = 40006 Then 
MsgBox "Socket error!" & vbNewLine & "The requested device might be offline.", vbCritical + vbSystemModal, "Socket error" 
Unload Form2 
End If 
End Sub 

Private Sub UpdateList_Timer() 
On Error Resume Next 
If List1.ListCount > 0 Then 
If UpdateListStatus = 0 Then 
TempList.Clear 

Socket1.SendData ("RESPOND_MESSAGE") 
Socket2.SendData ("RESPOND_MESSAGE") 

UpdateListStatus = 1 
UpdateList.Interval = 5000 
ElseIf UpdateListStatus = 1 Then 
List1.Clear 
For x = 0 To TempList.ListCount 
List1.AddItem (TempList.List(x)) 
Next x 

For X2 = 0 To List1.ListCount 
If List1.List(X2) = "" Then 'Check if we have any items that are nothing 
List1.RemoveItem (X2) 
End If 
Next X2 

Label1.Caption = "Connected clients: " & List1.ListCount 
UpdateListStatus = 0 
UpdateList.Interval = 10000 
End If 
End If 
End Sub 

Private Sub Socket1_DataArrival(ByVal bytesTotal As Long) 
On Error Resume Next 
Dim TempString As String 
Dim TempString2 As String 
Dim position As Integer 

Socket1.GetData TempString, vbString 
    position = InStr(1, TempString, "DEVICE_NAME=") 
    If position > 0 Then 'It is a device name command from a client 
     TempString2 = Mid(TempString, InStr(TempString, "=") + 1) 
     List1.AddItem (TempString2 + " - " + Socket1.RemoteHostIP) 
     Label1.Caption = "Connected clients: " & List1.ListCount 
     TempString2 = "" 
    End If 
    position = 0 
    position = InStr(1, TempString, "DEVICE_NAME_REP=") 
    If position > 0 Then 'It is a device name command from a client 
     TempString2 = Mid(TempString, InStr(TempString, "=") + 1) 
     DeviceNameLabel.Caption = "Device name: " & TempString2 
     TempString2 = "" 
    End If 
    position = 0 
    position = InStr(1, TempString, "DEVICE_FIRMWARE=") 
    If position > 0 Then 'It is a device firmware command from a client 
     TempString2 = Mid(TempString, InStr(TempString, "=") + 1) 
     DeviceFirmwareLabel.Caption = "Firmware version: " & TempString2 
     Unload Form2 'Since this is the last piece we will be receiving we can close this window 
     TempString2 = "" 
    End If 
    position = 0 
    position = InStr(1, TempString, "DEVICE_OK=") 
    If position > 0 Then 'It is a device respond command from a client 
     TempString2 = Mid(TempString, InStr(TempString, "=") + 1) 
     TempList.AddItem (TempString2 + " - " + Socket1.RemoteHostIP) 
     Label1.Caption = "Connected clients: " & List1.ListCount 
     TempString2 = "" 
    End If 
    position = 0 
    position = InStr(1, TempString, "DEVICE_REBOOTING") 
    If position > 0 Then 'It is a device respond command from a client 
     Socket1.Close 
     TempString2 = "" 
    End If 
Text1.Text = Text1.Text & TempString & vbNewLine 
TempString = "" 
position = 0 
TempString2 = "" 
End Sub 

Private Sub Socket2_DataArrival(ByVal bytesTotal As Long) 
On Error Resume Next 
Dim TempString As String 
Dim TempString2 As String 
Dim position As Integer 

Socket2.GetData TempString, vbString 
    position = InStr(1, TempString, "DEVICE_NAME=") 
    If position > 0 Then 'It is a device name command from a client 
     TempString2 = Mid(TempString, InStr(TempString, "=") + 1) 
     List1.AddItem (TempString2 + " - " + Socket2.RemoteHostIP) 
     Label1.Caption = "Connected clients: " & List1.ListCount 
     TempString2 = "" 
    End If 
    position = 0 
    position = InStr(1, TempString, "DEVICE_NAME_REP=") 
    If position > 0 Then 'It is a device name command from a client 
     TempString2 = Mid(TempString, InStr(TempString, "=") + 1) 
     DeviceNameLabel.Caption = "Device name: " & TempString2 
     TempString2 = "" 
    End If 
    position = 0 
    position = InStr(1, TempString, "DEVICE_FIRMWARE=") 
    If position > 0 Then 'It is a device firmware command from a client 
     TempString2 = Mid(TempString, InStr(TempString, "=") + 1) 
     DeviceFirmwareLabel.Caption = "Firmware version: " & TempString2 
     Unload Form2 'Since this is the last piece we will be receiving we can close this window 
     TempString2 = "" 
    End If 
    position = 0 
    position = InStr(1, TempString, "DEVICE_OK=") 
    If position > 0 Then 'It is a device respond command from a client 
     TempString2 = Mid(TempString, InStr(TempString, "=") + 1) 
     TempList.AddItem (TempString2 + " - " + Socket2.RemoteHostIP) 
     Label1.Caption = "Connected clients: " & List1.ListCount 
     TempString2 = "" 
    End If 
    position = 0 
    position = InStr(1, TempString, "DEVICE_REBOOTING") 
    If position > 0 Then 'It is a device respond command from a client 
     Socket2.Close 
     TempString2 = "" 
    End If 
Text1.Text = Text1.Text & TempString & vbNewLine 
TempString = "" 
position = 0 
TempString2 = "" 
End Sub 


Private Sub Socket1_ConnectionRequest(ByVal requestID As Long) 
If Socket1.State <> sckClosed Then 
    Socket1.Close 
    ' Accept the request with the requestID 
    ' parameter. 
    Socket1.Accept requestID 
End If 
End Sub 

Private Sub Socket2_ConnectionRequest(ByVal requestID As Long) 
If Socket2.State <> sckClosed Then 
    Socket2.Close 
    Socket2.Accept requestID 'Allow the connection 
End If 
End Sub 

`

+0

Comment vous connectez? TCP? Si oui, utilisez-vous des ports différents? poster du code s'il vous plaît. – Stavm

+0

Désolé, accidentellement touché entrer bientôt, alors pourquoi il n'y avait pas de code disponible:/Oh et j'utilise TCP, le port 2444 pour socket1 et le port 2445 pour socket2 –

Répondre

1

Okay donc j'ai pu trouver un très bon exemple de code pour un serveur multi-client Et aussi j'ai été en mesure de comprendre que le délai d'attente que j'ai créé était trop court, c'est pourquoi il disparaissait de la liste. Parfois, il faut 10 secondes pour recevoir une réponse et le délai d'expiration a été fixé à seulement 5 secondes MAX. Mais encore merci pour essayer de me aider :)

Le lien vers le code exemple: LINK

1

Il y a beaucoup là pour creuser à travers (vous voudrez probablement essayer de créer un MCVE du problème juste pour faire votre propre débogage plus facile), mais à première vue, ces gestionnaires d'événements ConnectionRequest me semblent suspects. Le Winsock Control ConnectionRequest Event documentation dit à "Utiliser la méthode Accept (sur une nouvelle instance de contrôle) pour accepter une connexion entrante." Vous essayez d'utiliser en quelque sorte la même instance de contrôle, ce qui est peut-être un moyen de le faire, mais ce n'est pas l'approche standard.

Si ma mémoire est bonne (il y a eu toujours depuis que j'ai eu affaire à ce sujet), vous voulez créer un Control Array des contrôles Winsock et load une nouvelle instance au moment de l'exécution pour gérer chaque nouvelle connexion (et le décharger lorsque la connexion est complet). Le contrôle "écoute" et le contrôle "gestion d'une connexion en cours" doivent être des instances différentes. Ainsi, chaque instance gère sa propre connexion avec son propre état et l'écouteur est disponible pour gérer les nouvelles connexions entrantes.

+0

Je vais faire une version MCVE, mais je ne vois pas quel est le problème avec l'événement ConnectionRequest. Sauf si je ne sais pas quelque chose que tu sais. Oh et j'ai utilisé un tableau winsock avant cela, mais cela m'a donné encore plus de problèmes, comme si j'avais besoin d'envoyer un message à un certain client, je devais trouver ce que Winsock était connecté à ce client spécifique. –

+0

Je viens de faire une version MCVE avec juste les bases et il perd encore la connexion:/Donc, il y a quelque chose de mal à garder une connexion. Je pourrais même le voir dans le plein que quand j'envoie le message de réponse de force je reçois seulement une réponse de 1 client et celui qui perd sa connexion est toujours celui qui s'est connecté en premier, donc je pense que le deuxième winsock interfère avec le premier winsock. Ne sait pas pourquoi mais ça arrive –

+1

@ SanderB.Well oui, votre événement ConnectionReceived dit que la première chose à faire est de fermer sa connexion existante, c'est ce qu'il fait.Comment géreriez-vous plusieurs connexions sans avoir besoin de garder une trace de la connexion qui est traitée par quel contrôle? –