C# 异步Telnet服务器数据接收问题

C# 异步Telnet服务器数据接收问题,c#,sockets,asynchronous,protocol-buffers,C#,Sockets,Asynchronous,Protocol Buffers,我正在使用异步Begin/End方法编写一个telnet服务器。我面临的问题是确定缓冲区中哪些是实际数据,哪些不是。网络编码对我来说有点陌生,但我一直在努力研究这个问题,却没有找到答案 public bool Start(IGame game) { // Get our server address information. IPHostEntry serverHost = Dns.GetHostEntry(Dns.GetHostName()); IPEndPoint s

我正在使用
异步Begin/End
方法编写一个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)
    {
    }
}
然后是播放器。接收数据

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为止

我想有更好的办法吗?有人能给我指出一个正确的方向吗?我应该如何确定缓冲区中有哪些数据,或者我可以不必使用预先确定的缓冲区大小就可以这样做

因此,当调用开始接收时,我需要提供一个预定大小的缓冲区。这样做,我的缓冲区数组中就有了未使用的字节。它们的值都是0,所以我假设我可以在数组中循环,并从索引0开始构建一个新的数组,直到达到值0为止

不,那不是你应该做的。相反,在您的回调(
ReceiveData
)中,您已经在调用—结果是您读取的字节数。这就是你应该使用多少缓冲区

但是,在再次调用
BeginReceive
之前,应将已读取的数据从缓冲区中复制出来,否则可能会导致下一位数据在开始使用之前覆盖刚刚读取的数据

比如:

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

我不建议您使用
编码。默认情况下,
将字节转换为文本-相反,您应该决定使用哪种编码,并坚持使用。如果您使用的编码并不总是每个字符一个字节,那么您最终会遇到一个稍微棘手的情况,因为这样您可能会收到一个包含部分字符的缓冲区。在这一点上,您需要保持一个可以保持部分字符读取状态的状态。

我可能不太清楚我当时是怎么说的。我是指调用BeginReceive时,所需的参数用于设置大小的缓冲区。@JohnathonSullinger:是的,这是一个要求-就像调用
Stream.Read
。在我的
ReceiveData
中,我实际上已经调用EndReceive并捕获缓冲区大小(尽管我没有意识到该值是什么)。为了澄清我最初的一些问题,如果我的缓冲区中有数据,并且我得到了EndReceive读取的字节数,有没有办法将我现有的缓冲区拆分成一个新数组,只提取接收到的字节?我想知道是否有类似于
byte[]receivedData=this.buffer.Range[0,receivedDataSize]
@JohnathonSullinger:你可以创建一个新数组(
newbyte[size]
),然后使用
array.Copy
Buffer.BlockCopy
复制数据。框架中没有实现这一点的现有方法,但是您可以轻松地创建自己的方法。但是,既然要将其转换为字符串,为什么不直接使用
Encoding.GetString(byte[],int,int)