我正在使用TCP之上的自有协议编写游戏服务器。
数据包的格式为varint packet_length,后跟该字节数。

要读取varint,我必须逐字节读取。但是Stream或NetworkStream不提供ReadByteAsync方法,这意味着如果套接字没有可用数据,则任务将因此阻塞,因此线程将阻塞。当然,我会用BufferedStream包装NetworkSteam,但是即使BufferedStream的ReadByte也使用同步读取来读取它的缓冲区。这将阻止。

服务器大致如下所示:

public static void Main(string[] args)
{
    var listener = new TcpListener(new IPEndPoint(IPAddress.Any, 25000));
    while (true)
    {
        var client = listener.AcceptTcpClientAsync().Result;
        HandleClient(client).ContinueWith(t => {
            if (t.IsFaulted)
            {
                Console.WriteLine(t.Exception);
            }
        });
    }
}

public static async Task HandleClient(TcpClient client)
{
    await Task.Yield();
    while (true)
    {
        // read packet
        // using ReadByte here would block if data is not available, which means I'm wasting a thread?
    }
}


为什么不存在ReadByteAsync?还是我错过了什么?

最佳答案

只需使用现有的方法ReadAsync,使其对您有利:

private static async Task<byte> ReadByteAsync(Stream s)
{
    byte[] buffer = new byte[1];

    await s.ReadAsync(buffer, 0, 1);

    return buffer[0];
}


ya的作业:将buffer分解为类级字段,这样就不会在每个方法调用中都创建它。

07-24 09:23