2017-08-25 2 views
0

Momentan entwickle ich ein Tool, mit dem ich die Verzögerung zwischen Netzwerkverbindungen mit VB6 und einem Arduino UNO mit Ethernet-Shield messen kann. Jetzt habe ich einige Probleme mit dem Server-Code (das VB6-Programm). Ich habe 2 Winsocks mit beiden verschiedenen Ports und sie beide hören für den Arduino-Client zu verbinden. Jetzt, wenn ich nur eine aktive Verbindung habe, geht nichts schief und alles funktioniert gut, aber sobald der zweite Client sich verbindet, fängt der ganze Server an verrückt zu werden. Plötzlich meldet es, dass der erste Client, der die Verbindung verloren hat, die Verbindung verloren hat. Kurz gesagt, der Server will nur 2 Clients gleichzeitig, aber ich brauche sie wirklich:/Was läuft falsch?VB6 Winsock-Server und mehrere Arduino-Clients Ausgabe

Ich werde schnell erklären, was bestimmte Befehle tun, die über den Winsock an oder von dem Server gesendet werden.

"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.

Mein 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

Wie verbinden Sie? TCP? Wenn ja, verwenden Sie unterschiedliche Ports? poste bitte einen Code. – Stavm

+0

Entschuldigung, aus Versehen eintrage, so dass es keinen Code gab:/Oh und ich benutze TCP, Port 2444 für Socket1 und Port 2445 für Socket2 –

Antwort

1

Okay, so konnte ich einen sehr guten Beispielcode für einen Multi-Client-Server finden Und auch ich konnte herausfinden, dass die Zeitverzögerung, die ich erstellt habe, WAY zu kurz war, deshalb war es verschwunden Die Liste. Manchmal dauert es 10 Sekunden, um eine Antwort zu erhalten, und das Timeout wurde auf nur 5 Sekunden MAX eingestellt. Aber immer noch Dank für den Versuch, mir :)

Der Link zum Beispielcode zu helfen: LINK

1

es viel gibt es zu graben, durch (Sie wollen wahrscheinlich versuchen, ein MCVE des Problems zu erstellen, Ihr eigenes Debugging zu machen einfacher), aber auf den ersten Blick scheinen diese ConnectionRequest Event-Handler mir suspekt. Die Winsock Control ConnectionRequest Event documentation sagt zu "Verwenden Sie die Accept-Methode (auf einer neuen Steuerungsinstanz), um eine eingehende Verbindung zu akzeptieren." Sie versuchen, die gleiche Kontrollinstanz irgendwie zu verwenden, was vielleicht eine Möglichkeit ist, aber nicht die Standardmethode ist.

Wenn der Speicher dient (es war immer da ich damit beschäftigt haben), können Sie eine Control Array von Winsock Controls erstellen möchten, und load eine neue Instanz zur Laufzeit bei jeder neuen Verbindung zu behandeln (und es zu entladen, wenn die Verbindung ist komplett). Das "Zuhören" -Steuerelement und das "Behandeln einer aktuellen Verbindung" -Steuerung müssen unterschiedliche Instanzen sein. Auf diese Weise behandelt jede Instanz ihre eigene Verbindung mit ihrem eigenen Status, und der Listener ist für die Behandlung neuer eingehender Verbindungen verfügbar.

+0

Ich mache eine MCVE-Version, aber ich sehe nicht Was ist mit dem ConnectionRequest-Ereignis falsch? Es sei denn, ich weiß nichts, was du weißt. Oh, und ich habe vorher ein Winsock-Array verwendet, aber es gab mir noch mehr Probleme, als ob ich eine Nachricht an einen bestimmten Client senden müsste, um herauszufinden, was Winsock mit diesem bestimmten Client verbunden war. –

+0

Ich habe gerade eine MCVE-Version mit nur den Grundlagen gemacht und sie verliert immer noch die Verbindung:/Es ist also etwas falsch, eine Verbindung aufrecht zu erhalten. Ich könnte es sogar in der vollen sehen, dass, wenn ich die Kraftantwortnachricht sende, ich nur eine Antwort von 1 Klienten bekomme und der, der seine Verbindung verliert, ist immer der, der zuerst in Verbindung brachte, also denke ich, dass der zweite winsock das stört erster Winsock. Ich weiß nicht warum, aber es passiert –

+1

@ SanderB.Well ja, Ihr ConnectionReceived-Ereignis sagt, das erste, was zu tun ist, ist seine bestehende Verbindung zu schließen, so dass es ist, was es tut.Wie würden Sie mehrere Verbindungen verwalten, ohne nachverfolgen zu müssen, welche Verbindung von welcher Steuerung bearbeitet wird? –