2017-08-25 149 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事件表明,要做的第一件事是關閉它的現有連接,所以這就是它的作用。你將如何處理多個連接,而無需跟蹤哪個控件正在處理哪個連接? –