我正在寻找最佳实践以满足以下要求:
- 一个异步处理多个客户端 socket 的框架
- 每个传入的消息协议规定每个消息都是字符串格式,并用换行符“\n”标记为完成。
- 我对客户端有完全控制权,但对服务器端没有。服务器接受并发送基于字符串的消息,并使用换行符标记消息的完成。
- 我希望能够在任何给定时间通过每个连接的 socket 发送消息(每个 socket 都可以接收和发送消息)。
- 传入的消息应通过回调函数转发。
- 我希望能够在我的实现中选择所有连接的完整传入消息是否路由到一个单一的回调函数,或者每个 socket 客户端是否实现其自己的回调函数。
- 我最多连接 4 个客户端/sockets。因此,我寻找利用这样有限数量的 sockets 的建议,但仍能同时管理所有这些 sockets。
我想知道,在针对 .Net 4.5 的情况下,我是否应该使用实现了 IAsyncResult 回调的 BeginReceive
和 EndReceive
的框架。是否有更好的解决方案,例如使用 NetworkStream 或其他 API 选项?对于 BeginReceive/EndReceive 实现真正困扰我的是,结束接收后我必须再次调用 BeginReceive 并重新注册回调函数。这对我来说听起来像是一种可怕的开销。为什么不能随时异步添加新数据,并且同时另一个上下文构建完整的消息,然后通过引发事件路由这些消息呢?
使用 IAsyncResult 的论点经常是处理线程已经被照顾好了,但是以下方案有何不妥呢:使用 NetworkStream 并简单地从流中读取和写入。如前所述,只交换字符串消息,并且每个协议的每个消息都由换行符字符标记为完成。一个单独的任务/线程将通过 ReadLine()
轮询 streamreader(基于 networkstream)。这可能是最简单的方法,不是吗?
我基本上想问的是,如何使以下代码真正实现异步?
public class SocketClient
{
private TcpClient client;
private StreamReader reader;
private StreamWriter writer;
public event Action<string> MessageCallback;
public SocketClient(string hostname, int port)
{
client = new TcpClient(hostname, port);
try
{
Stream stream = client.GetStream();
reader = new StreamReader(stream);
writer = new StreamWriter(stream);
writer.AutoFlush = true;
//Start Listener on port
StartListener();
}
catch (Exception e)
{
throw new Exception(e.ToString());
}
}
public void StartListener()
{
Task task = Task.Factory.StartNew(() =>
{
while (true)
{
if (MessageCallback != null)
{
MessageCallback(reader.ReadLine());
}
//Thread.Sleep(200);
}
});
}
}