2017-08-25 125 views
0

现在我正在开发一个工具,可以测量使用VB6的网络连接和具有以太网盾的arduino UNO之间的延迟。 现在我正面临一些与服务器代码(VB6程序)有关的问题。 我有两个不同端口的winsock,他们都在监听arduino客户端连接。现在,如果我只有一个活动连接,没有任何问题,一切正常,但只要第二个客户端连接整个服务器开始疯狂。突然它报告说,第一个连接的客户端丢失了连接,所以总之服务器并不想每次连接2个客户端,但我确实需要它:/出了什么问题?VB6 winsock服务器和多个arduino客户端问题

我会尽快解释通过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.

我的代码:

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

如何连接? TCP?如果是这样,你使用不同的端口?请张贴一些代码。 – Stavm

+0

对不起,无意中碰到了很快进入的方式,以便为什么没有可用的代码:/哦,我正在使用TCP,端口2444为socket1和端口2445为socket2 –

回答

1

好吧,所以我能够找到一个多客户端服务器的一个很好的示例代码 而且我能够弄清楚,我创建的超时延迟是太短,所以这就是为什么它从消失列表。有时需要10秒钟才能收到响应,超时时间只能设置为5秒MAX。 不过还是感谢试图帮助我:)

链接到示例代码:LINK

1

有很多在那里挖通(你可能想尝试创建一个问题的MCVE只是为了让自己的调试更容易),但乍一看那些ConnectionRequest事件处理程序似乎对我怀疑。 Winsock Control ConnectionRequest Event documentation表示“使用Accept方法(在新的控件实例上)接受传入连接”。你试图以某种方式使用相同的控制实例,这可能有办法做,但不是标准方法。

如果没记错的(它已经永远,因为我已经经历了这一点),你要创建的Winsock控件的Control Arrayload在运行时处理每个新连接的新实例(和卸载它时,连接做完了)。 “监听”控件和“处理当前连接”控件需要是不同的实例。这样,每个实例都会使用自己的状态处理自己的连接,并且侦听器可用于处理任何新的传入连接。

+0

我将制作一个MCVE版本,但我没有看到ConnectionRequest事件有什么问题。除非我不知道你知道的东西。哦,我在这之前使用了一个winsock数组,但它给了我更多的问题,比如如果我需要发送消息给某个客户端,我需要找到哪些winsock连接到了特定的客户端。 –

+0

我刚刚做了一个基本的MCVE版本,它仍然失去连接:/所以保持连接有问题。我甚至可以在完整的视图中看到,当我发送强制响应消息时,我只能得到来自1个客户端的响应,并且失去连接的那个始终是首先连接的那个,所以我认为第二个winsock会干扰第一个winsock。不知道为什么,但它发生了。 –

+1

@ SanderB.Well是的,你的ConnectionReceived事件表明,要做的第一件事是关闭它的现有连接,所以这就是它的作用。你将如何处理多个连接,而无需跟踪哪个控件正在处理哪个连接? –