传递对象的异步套接字示例?

时间:2011-02-06 16:52:26

标签: c# .net sockets network-programming

我需要创建一个服务器进程,它可以将高频数据(每秒1000次更新)推送到大约50个客户端。我认为最好的方法是使用SocketAsyncEventArgs类型的异步套接字。

客户 - >服务器连接将长期运行至少几天无限期。我打算让服务器进程监听,客户端连接,服务器开始将数据推送到客户端。

有人能指点我或告诉我一个如何做到这一点的例子吗?我找不到任何显示服务器进程将对象推送到客户端的示例。

编辑:这是一个gigibit局域网。使用16核和24GB内存的Windows服务器

感谢

3 个答案:

答案 0 :(得分:1)

首先,您需要更多的要求。你的服务器有很多肌肉,但是如果你不做必须做的事情,它将会失败。

  1. 客户端可以没有一些数据吗?我的意思是,数据流是否需要以正确的顺序到达另一侧,没有任何下降?

  2. '数据'有多大?几个字节或?

  3. 事实:Windows上的调度间隔是10毫秒。

  4. 事实:无论你何时发送,客户都会收到它,具体取决于很多东西 - 网络配置,中间路由器数量,客户端处理器负载等等。所以你需要一些时间戳

  5. 根据所有这些,您可以设计一个优先级队列,其中一个线程为其服务​​,并为每个客户端发送UDP数据报。此外,由于(4)生效,您可以将一些数据“聚集”在一起,每100次数据每次更新10次。

    如果您想要实现其他目标,那么这里需要使用大量优质网络设备的LAN。

答案 1 :(得分:0)

约会或29西?它可以节省重新发明的轮子。关于amqp或zeromq的Dunno他们也可以正常工作....

答案 2 :(得分:0)

如果您想使用.NET套接字创建此服务器 - 客户端项目,那么这是对所需内容的一个很好的概述:

由于服务器将同时向多个客户端传输数据,因此您需要使用异步Socket.Beginxxx方法或SocketAsyncEventArgs类。

您将有客户端连接到您的服务器。服务器将接受这些连接,然后将新连接的客户端添加到内部客户端列表。

您将在服务器中运行一个线程,该线程会定期向客户端列表中的所有套接字发送通知。如果在向套接字发送数据时发生任何异常/错误,则从列表中删除该客户端。

您必须确保对客户端列表的访问是同步的,因为服务器是多线程应用程序。

您不必担心缓冲发送数据,因为TCP堆栈负责处理。如果您根本不想缓冲数据(即让套接字立即发送数据),则将Socket.NoDelay设置为true。

您似乎不需要来自客户端的任何数据,但如果您这样做,则必须确保您的服务器具有Socket.BeginReceive循环,如果使用Socket.BeginXXX模式或{{ 1}}方法,如果使用Socket.ReceiveAsync

一旦在服务器和客户端之间建立了数据连接和传输,就需要担心客户端和服务器之间对象的序列化和反序列化。

服务器上发生的序列化很容易,因为您可以使用BinaryFormatter或其他编码器对对象进行编码并将数据转储到套接字上。

另一方面,在客户端上发生的反序列化可能非常复杂,因为一个对象可以跨越多个数据包,并且您可以在一个数据包中拥有多个对象。您基本上需要一种方法来识别流中对象的开头和结尾,以便您可以取出对象数据并对其进行反序列化。

执行此操作的一种方法是将数据嵌入到众所周知的协议(如HTTP)中,然后使用该格式发送。不幸的是,这也意味着您必须在客户端编写HTTP解析器。这不是一件容易的事。

另一种方法是利用像Google protocol buffers这样的现有编码方案。这种方法需要学习如何使用协议缓冲区堆栈。

您还可以将数据嵌入XML结构中,然后在客户端使用流到XML解码器。这可能是最简单的方法,但效率最低。

正如您所看到的,这不是一个简单的项目,但您可以开始使用Socket.BeginSend示例herehere以及SocketAsyncEventArgs example here

其他提示:

通过让客户端维护与服务器的两个连接以实现冗余,您可以提高通信的可靠性。原因是TCP连接需要一段时间才能建立,因此如果一个连接失败,您仍然可以在客户端尝试重新连接失败的连接时从另一个接收数据。

您可以考虑将TCPClient类用于客户端实现,因为它主要是从网络连接中读取流。