2012-07-06 64 views
2

我是C#的新手,主要完成过去基于Web的编码。我正在创建一个将与单个客户端通信的TCP服务器。我知道我需要多个线程,因为我不希望我的程序阻止等待连接(或读取数据,发送等)。针对单个客户端的TCP服务器模型

到目前为止,我已经编写了一个简单的测试应用程序,其中包含一个用于与客户端进行通信的GUI和类。主要的GUI类创建通信类的一个实例。我在BackgroundWorker中调用了socket.accept,并试图将连接的套接字传递回RunWorkerCompletedEventArgs.Result中的通信类。这一直没有奏效。我可以打破DoWork方法并查看套接字已连接。然后,我将DoWorkEventArgs.Result设置为连接的套接字并尝试将其传递回通信类。在RunWorkerCompleted方法中,套接字不再连接。

我可能对如何为单个客户端实现TCP服务器有错误的想法。我见过的所有例子都是为多个客户设计的,但我将会处理一个客户。我无法控制客户端,只是试图与之通信。

如何将连接的套接字从BackgroundWorker传递回主类,或者更好地构造代码是我需要的。

更新:

我不控制客户端。它是一个嵌入式Linux设备。协议非常简单。大小头部,后跟数据字节。

目标是.NET 2.0。看来WCF只能在.NET 3.0及更高版本上使用。

更新:

我的代码将被发送命令给客户端和接收数据的后面。我的代码将是一个需要不断发送/接收数据的长时间运行的应用程序。

+1

为什么需要手动编程套接字?你不想使用WCF吗? – abatishchev 2012-07-06 18:45:24

+0

通常,单个或多个客户端之间的服务器没有区别。您可以为每个客户端提供更高的负载。 – abatishchev 2012-07-06 18:47:03

+0

我建议尝试'任务并行库'而不是BGW。 – abatishchev 2012-07-06 18:47:34

回答

0

当您问到其他设计思路时,我的建议(我曾在Java和.NET中使用过这种模式)在过去的4年中在我的项目中证明它工作得很好!) 主要思想是:你不应该把你的套接字放回主类。你的后台工作者应该阻塞等待客户端的套接字,一旦它获得一个连接,它会循环并从客户端读取数据。后台工作人员将通过thread safe queue将收到的数据包(二进制格式,不要在这里解析数据,因为它应该是主类的责任)通知主类。主类可以循环(或更好地使用blocking queue)并通过后台工作进程处理来自客户端的所有新消息。

这样你就可以将你的代码分成两个不同的层。工作人员负责与客户和主要客户谈话,其责任是了解客户说什么并且有选择地回复(仍然通过工人)

编辑从您的编辑中,我看到您正在.NET2.0。不幸的是,这个版本的框架没有线程安全阻塞队列,因为它们是在.NET4中引入的。仍然可以找到许多基于.NET2的线程安全队列实现。

+0

Queue.Synchronized在.Net 2.0中可用。 [链接] http://msdn.microsoft.com/en-us/library/system.collections.queue.synchronized(v = vs.80).aspx我会通知事件的主线程,或有一个循环检查排队新的数据包? – 2012-07-06 20:25:25

+0

@JamesCrow对不起,我的意思是阻塞队列不是线程安全队列:) – GETah 2012-07-06 20:31:41

+0

我应该能够使用BackgroundWorker ReportProgress方法通知主线程新消息已到达。我正在修改我的通信类,以便在.Net 2.0中试用。 – 2012-07-06 20:42:30