2014-01-05 54 views
1

我正在使用async Begin/End方法編寫telnet服務器。我遇到的問題是確定我的緩衝區內的實際數據是什麼,什麼不是。網絡編碼對我來說有點新意,但我試圖研究這一點,但一直未能找到答案。異步Telnet服務器數據接收問題

public bool Start(IGame game) 
{ 
    // Get our server address information. 
    IPHostEntry serverHost = Dns.GetHostEntry(Dns.GetHostName()); 
    IPEndPoint serverEndPoint = new IPEndPoint(IPAddress.Any, this.Port); 

    // Instance the server socket, bind it to a port and begin listening for connections. 
    this._ServerSocket = new Socket(serverEndPoint.Address.AddressFamily, SocketType.Stream, ProtocolType.Tcp); 
    this._ServerSocket.Bind(serverEndPoint); 
    this._ServerSocket.Listen(this.MaxQueuedConnections); 

    this._ServerSocket.BeginAccept(new AsyncCallback(Connect), this._ServerSocket); 
    return true; 
} 

private void Connect(IAsyncResult result) 
{ 
    var player = new BasePlayer(); 
    try 
    { 
     player.Game = this.Game; 
     player.Connection = this._ServerSocket.EndAccept(result); 

     lock (this.Connections) 
     { 
      this.Connections.Add(player); 
     } 

     // Pass all of the data handling for the player to itself. 
     player.Connection.BeginReceive(player.Buffer, 0, player.BufferSize, SocketFlags.None, new AsyncCallback(player.ReceiveData), player); 

     // Fetch the next incoming connection. 
     this._ServerSocket.BeginAccept(new AsyncCallback(Connect), this._ServerSocket); 
    } 
    catch (Exception) 
    { 
    } 
} 

然後player.ReceiveData ..

public void ReceiveData(IAsyncResult result) 
{ 
    int bytesRead = this.Connection.EndReceive(result); 

    if (bytesRead > 0) 
    { 
     // TODO: Parse data received by the user. 

     //Queue the next receive data. 
     this.Connection.BeginReceive(this.Buffer, 0, this.BufferSize, SocketFlags.None, new AsyncCallback(ReceiveData), this); 
     var str = System.Text.Encoding.Default.GetString(Buffer); 
    } 
    else 
    { 
     this.Disconnect(result); 
    } 
} 

因此,當我打電話BeginReceive,我需要提供一個預定大小的緩衝器。在這樣做的時候,我最終在緩衝區數組中使用了未使用的字節。他們都有0的價值,所以我假設我可以遍歷數組,並建立一個新的索引0開始工作,直到我打到0值。

我想有一個更好的方法來做這個?有人可以請我指出正確的方向,我應該如何確定數據在我的緩衝區內,或者我可以做到這一點,而不必使用預定的緩衝區大小。

回答

2

所以當調用BeginReceive時,我需要提供一個預定大小的緩衝區。在這樣做的時候,我最終在緩衝區數組中使用了未使用的字節。他們都有0值,所以我假設我可以遍歷數組,並建立一個新的從索引0開始,直到我達到0值。

不,這不是你應該做。相反,在您的回調(ReceiveData)中,您已經調用了EndReceive - 結果是您讀取的字節數。 這就是你應該使用多少緩衝區。

然而,你應該你再打電話BeginReceive之前複製您讀出緩衝的數據,否則你可能最終與數據覆蓋剛剛讀取數據的下位你使用它之前, 。

因此,像:

string text = Encoding.ASCII.GetString(Buffer, 0, bytesRead); 
Connection.BeginReceive(this.Buffer, 0, this.BufferSize, SocketFlags.None, 
         new AsyncCallback(ReceiveData), this); 

我會建議你用Encoding.Default的字節轉換成文本 - 相反,你應該決定你使用的編碼,並堅持到底。如果您使用的編碼不一定是每字符一個字節,那麼最終會出現一個稍微棘手的情況,因爲您最終可能會收到一個帶有部分字符的緩衝區。此時你需要保留一個Decoder,它可以保持讀取部分字符的狀態。

+0

我發表該聲明時可能並不十分清楚。我指的是當我調用BeginReceive時,所需的參數用於設置大小的緩衝區。 –

+0

@JohnathonSullinger:是的,這是一個要求 - 就像調用Stream.Read一樣。 –

+0

在My'ReceiveData'中,我實際上已經調用EndReceive並捕獲緩衝區大小(儘管我沒有意識到這是什麼值)。因此,爲了澄清我的一些原始問題,如果我的緩衝區中有數據,並且我給出了EndReceive讀取的字節數,是否有辦法將現有緩衝區拆分爲只包含接收字節的新數組? –

相關問題