我想使用
那么写入呢?嗯,微软在这个主题上有一个通常的低质量教程,他们建议为每个操作编写冗长的
我知道这意味着轮询,但它将在一个预计大部分时间都处于活动状态的服务器上运行,并且我计划在空闲时进行一些Thread.Sleeps。
另一个问题是,我发送的消息被分成头部数组和正文数组。我能够连续发出两个BeginWrites吗?
此外,欢迎任何关于使用Socket或NetworkStream的意见。
NetworkStream
(或者也许是Socket
)来读写TCP连接。我想使用非阻塞操作,这样就不必处理多个线程,也不必处理如果某些线程在阻塞网络操作上停止时如何停止程序的问题。
NetworkStream.Read
的文档暗示它是非阻塞的(“如果没有可用于读取的数据,则Read方法返回0”),所以我猜我不需要异步回调来读取...对吧?那么写入呢?嗯,微软在这个主题上有一个通常的低质量教程,他们建议为每个操作编写冗长的
AsyncCallback
方法。这个回调中的代码有什么意义呢?client.BeginSend(byteData, 0, byteData.Length, SocketFlags.None,
new AsyncCallback(SendCallback), client);
...
private static void SendCallback(IAsyncResult ar)
{
try {
Socket client = (Socket)ar.AsyncState;
int bytesSent = client.EndSend(ar);
Console.WriteLine("Sent {0} bytes to server.", bytesSent);
// Signal that all bytes have been sent.
sendDone.Set();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
AsyncCallback
文档中写道,它是“在异步操作完成时调用的回调方法”。如果操作已经完成,为什么我们还要调用Socket.EndSend(IAsyncResult)
呢?同时,NetworkStream.BeginWrite
的文档说:“您必须创建一个实现了AsyncCallback
委托的回调方法,并将其名称传递给BeginWrite
方法。至少,您的状态参数必须包含NetworkStream
。”但为什么我“必须”这样做呢?我不能只是把IAsyncResult
存储在某个地方吗?_sendOp = client.BeginSend(message, 0, message.Length, SocketFlags.None, null, null);
...并定期检查它是否完成?
if (_sendOp.IsCompleted)
// start sending the next message in the queue
我知道这意味着轮询,但它将在一个预计大部分时间都处于活动状态的服务器上运行,并且我计划在空闲时进行一些Thread.Sleeps。
另一个问题是,我发送的消息被分成头部数组和正文数组。我能够连续发出两个BeginWrites吗?
IAsyncResult ar1 = _stream.BeginWrite(header, 0, header.Length, null, null);
IAsyncResult ar2 = _stream.BeginWrite(msgBody, 0, msgBody.Length, null, null);
此外,欢迎任何关于使用Socket或NetworkStream的意见。