2012-11-20 46 views
2

我有以下方法將rcon命令發送到遊戲服務器。C#udp套接字未收到整個郵件

public string sendCommand(string command) 
{ 
byte[] bufferTemp = Encoding.ASCII.GetBytes(command); 
byte[] bufferSend = new byte[bufferTemp.Length + 4]; 

//big enough to receive response 
byte[] bufferRec = new byte[65000]; 

//intial 4 characters as per standard 
bufferSend[0] = byte.Parse("255"); 
bufferSend[1] = byte.Parse("255"); 
bufferSend[2] = byte.Parse("255"); 
bufferSend[3] = byte.Parse("255"); 
int j = 4; 

for (int i = 0; i < bufferTemp.Length; i++) 
{ 
    bufferSend[j++] = bufferTemp[i]; 
} 

//send rcon command and get response 
try 
{ 
    this.server.Socket.Send(bufferSend, SocketFlags.None); 
    this.server.Socket.Receive(bufferRec); 
} 
catch (SocketException e) 
{ 
    MessageBox.Show(e.ToString(), "Error occured"); 
} 

string response = Encoding.ASCII.GetString(bufferRec); 

return response; 
} 

了所有的命令,我可以送可能的其中1返回更多的數據比別人,似乎* buffer_rec *字節數組只得到有關消息的1/4,但數組已被聲明爲足以包含所有數據。 在隨後的3個請求中,其餘數據會被輸出,就好像它以某種方式被緩衝了一樣。

我不知道這是爲什麼發生。如果你這樣做,可否請讓我知道如何解決這個問題?

謝謝 Crouz

+1

'接收方法讀取數據到緩衝區參數和**返回成功讀取的字節數**'http://msdn.microsoft.com/en-us/library/8s4y8aff.aspx –

+0

I知道它的確如此,但是我無法知道服務器應該返回多少字節,所以我不知道我什麼時候讀完數據。 – Crouzilles

+2

@ user1834208:即使除此之外,您應該總是*使用返回值。目前你正在從'bufferRec'的*整個*中創建一個字符串,而不管有多少數據被讀取。不要這樣做。接下來,你應該使用類似Wireshark的東西來查看網絡上發生的*實際情況。 –

回答

-2

好,似乎有6個小時的尋找到這後,我終於想出了一個解決方案,所以這裏是數據的接收做了小改動,請注意線程睡眠對於10ms來說,這似乎需要讓數據報在適當的時候到達。

//send rcon command and get response 
    string response = ""; 
    try 
    { 
     this.server.Socket.Send(bufferSend, SocketFlags.None); 

     do 
     { 
      int bytesReceived = this.server.Socket.Receive(bufferRec); 
      response += Encoding.ASCII.GetString(bufferRec, 0, bytesReceived); 
      System.Threading.Thread.Sleep(10); 
     } while (this.server.Socket.Available > 0); 
    } 
    catch (SocketException e) 
    { 
     MessageBox.Show(e.ToString(), "Error occured"); 
    } 

如果您覺得有處理這更好或更優雅的方式,不要猶豫,踩住我的代碼,而是通過提供一個替代這樣做,因爲我總是樂於學習新的東西。此致,Crouz

+0

好吧,我會咬人的。這是偶然的。你真的需要重新處理你的協議來包含一個頭信號的長度,並閱讀,直到你有這個字節數,或定義某種「消息結束」分隔符,以便您的消息解析代碼知道它什麼時候有一個消息。此外,請注意,您目前對數據包損壞(您需要爲此執行某種校驗和)或重新排序(如果您在意的話,您需要實現某種類型的序列號)具有零保護。或者只是使用TCP,你可以免費獲得很多上述內容。 – tomfanning

+1

鍵仍然是「Receive方法將數據讀入緩衝區參數,**返回成功讀取的字節數**」。您接收字節的循環應該簡單地將這些字節附加到緩衝區中。然後,**單獨**,您應該檢查該緩衝區以查看是否有一個或多個完整的消息要處理。 (「完整消息」是根據你的協議設計的。)當你有消息時,從緩衝區中刪除**只是那些字節**,做你需要做的任何處理(激發一個事件,無論如何),然後啓動再次循環。 – tomfanning

+0

我還沒有設計quake3協議,所以我無法對其進行更改,以告知我恐怕會留言多久。基本上我無法控制服務器端。我使用wireshark來檢查數據包,無處可見消息長度和消息標記的結尾(請注意,我對wireshark非常陌生,我可能會錯過某些東西)。 – Crouzilles