2011-10-15 70 views
0

我製作了一個TCP服務器,它可以同時與多個客戶端進行通信,但我似乎無法使其穩定。當其中一個客戶端向服務器發送100個數據包時,服務器只收到其中的幾個數據包。VB.NET異步套接字數據包丟失

Here's the client code in PasteBin。它顯示客戶端如何連接到服務器,然後在For循環中將100條消息發送到服務器。

And here's how the server handles the connection。我無法粘貼完整的源代碼,因爲它有數百行的長度,所以讓我知道它是否缺少任何必需的部分,我也會上傳它們。

回答

1

我在reddit上回答了你的問題,但是我想我會在這裏回覆以防別人正在尋找這種東西。

您的服務器處理讀取的方式有兩個問題。首先,你的客戶對象的構造:

Public Sub New(ByVal client As TcpClient) 
    'New client connects 
    Me.client = client 
    client.GetStream().BeginRead(New Byte() {0}, 0, 0, AddressOf Read, Nothing) 
End Sub 

的BeginRead指望你在可以傳遞給回調方法的方式收集數據;在這個例子中「閱讀」。通常,這是通過創建一個新對象來保存此異步操作的「狀態」並將其作爲最後一個參數傳遞給BeginRead來完成的。你的方法調用是創建一個新的字節數組,但是沒有引用它作爲方法的最後一個參數傳入。這意味着通過此調用讀取的數據在讀取後會消失,因爲它永遠不會傳遞到存儲它的方法。

其次,你的讀操作:

Public Sub Read(ByVal ar As IAsyncResult) 
    Dim reader As New StreamReader(client.GetStream()) 
    clientPacket &= reader.ReadLine() 
    client.GetStream().BeginRead(New Byte() {0}, 0, 0, AddressOf Read, Nothing) 
End Sub 

既然你沒有在在異步調用讀取的數據傳遞,你在這裏創建一個新的StreamReader從客戶端拉更多的數據。這不是一個異步方法調用。您的reader.ReadLine()調用會阻塞,直到遇到換行符,此時數據將被附加到clientPacket。然後,再次調用BeginRead,出現與上述相同的問題,這意味着您將失去更多數據。

此外,你永遠不會通過調用流上的EndRead()來清除AsyncResult對象,當CLR用完異步操作的工作線程時,最終會導致資源匱乏。

下面是我實現這種任務的一個例子。它是用C#編寫的,因爲這是我最舒服的,所以對此感到抱歉。 ;)

Client Code

Server Code

我希望這有助於!

+0

謝謝,讓它工作! – Scyte