这是从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
包装器有更优雅的方法吗?
答案 0 :(得分:2)
不,这不是从套接字读取数据的好方法。你在这里重新发明轮子; use NetworkStream
instead。我不知道为什么你需要使用低级Socket
API,但是,你不会。
相反,将Socket
包裹在呼叫网站的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,我建议使用the TcpClient API,而不是直接使用套接字。