2010-03-03 39 views
3

我目前正在创建一个Windows服务,它将创建到多台机器(所有机器上的相同套接字)的TCP连接,然后侦听这些机器上的“事件”。我试图编写代码来创建一个连接,然后产生一个线程,该线程侦听等待来自机器的数据包的连接,然后解码出现的数据包,并根据数据包的有效负载调用函数。在C#中创建多个TCP连接,然后等待数据

问题是我不完全知道如何在C#中做到这一点。有没有人有任何有用的建议或链接可能会帮助我做到这一点?

在此先感谢您的帮助!

+0

查看框架中的IHttpAsyncListener。它可能会为你做很多工作。 – 2010-03-03 03:58:23

回答

2

您可以异步接收每一个套接字连接,并解码来自其他机器来执行任务中的数据(您可以找到有关异步方法的一些有用的信息这里:http://msdn.microsoft.com/en-us/library/2e08f6yc.aspx)。

要创建连接,你可以这样做:

Socket sock = Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
sock.Connect(new IPEndPoint(address, port)); 

相同的方式,可以建立多个连接并保持在字典的列表(无论你喜欢)有引用。

用于异步接收套接字上的数据,你可以这样做:

sock.BeginReceive(buffer, 0, buffer.len, SocketFlags.None, new AsyncCallback(OnDataReceived), null); 

方法OnDataReceived将被调用时接收操作完成。

OnDataReceived方法你要做的:

void OnDataReceived(IAsyncResult result) 
{ 
    int dataReceived = sock.EndReceive(result); 
    //Make sure that dataReceived is equal to amount of data you wanted to receive. If it is 
    //less then the data you wanted, you can do synchronous receive to read remaining data. 

    //When all of the data is recieved, call BeginReceive again to receive more data 


    //... Do your decoding and call the method ...// 
} 

我希望这可以帮助你。

0

有一个单线程运行accept()来获取新的连接。对于您获得的每个新连接,使用线程池生成一个工作线程。

4

根据您计划支持的并发客户数量,每个连接线程体系结构可能会很快崩溃。原因在于,每个线程都需要大量资源。默认情况下,每个.NET线程获得1MB的堆栈空间,因此每个连接1MB加上任何开销。

相反,当支持多个连接的客户端时,通常会使用asynchronous methodssee here also),因为Windows将使用“完成端口”,在等待某个事件完成时基本释放该线程以执行其他操作。

为此,你会看的方法,如BeginAccept,BeginReceive,BeginSend等

更简单的方法也避免了使阻塞调用,避免了多线程是使用Socket.Select方法在一个循环。这允许单个线程服务多个套接字。该线程一次只能物理读取或写入一个套接字,但想法是您正在检查多个套接字的状态,这些套接字可能包含或不包含要读取的数据。

在任何情况下,每次连接的方法都会让您的头脑变得简单得多,但它确实存在严重的可伸缩性问题。我建议先用接受,接收,发送等同步方法来做这件事。然后再重构你的代码以使用异步方法,这样你就不会耗尽服务器的内存。

0

我不知道在你的情况下是否可能,但你有没有想过使用多台机器调用的WCF服务?你可以在一个自定义的Windows服务或IIS中承载它。在等待事件时它将消耗非常少的资源,而且编码要比所有低级可怕套接字的东西简单得多。它是自动异步的。你得到了很好的消息给你的服务,而不是你需要反序列化和/或解析的数据包。您可以使用任何数量的协议,例如REST或二进制。

您当然需要在发送消息的另一端创建进程。

只是一个想法...

干杯