简体   繁体   English

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

[英]async Telnet Server data receiving issues

I am writing a telnet server using the async Begin/End methods. 我正在使用async Begin/End方法编写telnet服务器。 The issue that I am having is determining what within my buffer is actual data and what is not. 我遇到的问题是确定缓冲区中的实际数据是什么,而不是实际数据。 Network coding is a bit new to me, but I've tried to research this and have not been able to find a answer. 网络编码对我来说有点新,但我尝试对此进行研究,但未能找到答案。

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)
    {
    }
}

and then the player.ReceiveData.. 然后是播放器。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);
    }
}

So when I call BeginReceive , I need to provide a buffer of a predetermined size. 因此,当我调用BeginReceive ,我需要提供预定大小的缓冲区。 In doing that, I end up with unused bytes in my buffer array. 这样,我最终在缓冲区数组中得到未使用的字节。 They all have the value of 0, so I am assuming that I can loop through the array and build a new one starting at index 0 and working until I hit a value of 0. 它们的值均为0,所以我假设我可以遍历该数组并从索引0开始构建一个新的数组,直到达到0为止。

I imagine there is a better way to do this? 我想有更好的方法可以做到这一点? Can someone please point me in the right direction as to how I should determine what the data is within my buffer or perhaps a way that I can do this without having to use a predetermined buffer size. 有人可以向我指出正确的方向,即我应该如何确定缓冲区中的数据,或者是无需使用预定缓冲区大小就可以做到的方式。

So when call BeginReceive, I need to provide a buffer of a predetermined size. 因此,在调用BeginReceive时,我需要提供预定大小的缓冲区。 In doing that, I end up with unused bytes in my buffer array. 这样,我最终在缓冲区数组中得到未使用的字节。 They all have the value of 0, so I am assuming that I can loop through the array and build a new one starting at index 0 and working until I hit a value of 0. 它们的值均为0,所以我假设我可以遍历该数组并从索引0开始构建一个新的数组,直到达到0为止。

No, that's not what you should do. 不,那不是你应该做的。 Instead, in your callback ( ReceiveData ) you're already calling EndReceive - and the result of that is the number of bytes you read. 相反,在回调( ReceiveData )中,您已经在调用EndReceive其结果是读取的字节数。 That's how much of the buffer you should use. 那就是您应该使用多少缓冲区。

However, you should copy the data you've read out of the buffer before you call BeginReceive again, otherwise you may end up with the next bit of data overwriting the just-read data before you get to use it. 但是,您应该在再次调用BeginReceive 之前将已读取的数据复制到缓冲区BeginReceive ,否则,在使用之前 ,可能会遇到下一点数据覆盖刚刚读取的数据的情况。

So something like: 所以像这样:

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

I would not suggest that you use Encoding.Default to convert the bytes to text - instead, you should decide which encoding you're using, and stick to that. 建议您使用Encoding.Default将字节转换为文本-相反,您应该确定所使用的编码,并坚持使用。 If you use an encoding which isn't always one-byte-per-character, you'll end up in a slightly trickier situation, as then you might end up receiving a buffer with part of a character. 如果您使用的编码不总是每个字符一个字节,那么您将遇到一种更加棘手的情况,因为这样您最终可能会收到带有一部分字符的缓冲区。 At that point you need to keep a Decoder which can maintain state about partial characters read. 到那时,您需要保留一个Decoder ,该Decoder可以保持有关部分字符读取状态。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM