异步/等待套接字接收数据问题

本文关键字:数据 问题 套接字 等待 异步 | 更新日期: 2023-09-27 18:06:41

这是从Socket读取数据的好方法吗?

public class StateObject : IDisposable
{
    private const int _bufferSize = 1024;
    public byte[] Buffer { get; } = new byte[_bufferSize];
    public int BufferSize { get; } = _bufferSize;
    public MemoryStream MsStream { get; }
    public EnhStateObject()
    {
        MsStream = new MemoryStream();
    }
    public void Dispose()
    {
        MsStream.Dispose();
    }
}
public async static Task<int> ReceiveAsync(this Socket client, StateObject state)
{
    var task = await await Task<int>.Factory.FromAsync(
    (cb, s) => client.BeginReceive(state.Buffer, 0, state.BufferSize, SocketFlags.None, cb, s),
    client.EndReceive, null).ContinueWith(t =>
    {
        state.MsStream.Write(state.Buffer, 0, t.Result);
        return t;
    });
    if (task == state.BufferSize) await client.ReceiveAsync(state);
    return task;
}

我的意思是,通过递归调用在对象外部传输并将接收到的信息存储在对象中。

或者是否有更优雅的方法使用相同的FromAsync包装器来做到这一点?

异步/等待套接字接收数据问题

不,这不是从套接字读取数据的好方法。你这是在重新发明轮子;用NetworkStream代替。我不知道为什么您需要使用低级别Socket API,但是,好吧,您不需要。

相反,将Socket包装在callsite的NetworkStream中,如下所示:

Socket socket = ....;
Stream stream = new NetworkStream(socket);

然后你可以像你期望的那样使用ReadAsync()读取数据(额外的好处:没有状态对象传递,你可以在测试中用标准的MemoryStream模拟流)

var buffer = new byte[1024];
var bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length);

如果你正在使用Tcp,我建议使用TcpClient API,而不是直接使用套接字。