我正在使用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
分解为类级字段,这样就不会在每个方法调用中都创建它。