2011-04-21 51 views
2

当谈论用C#编程的套接字术语阻塞是什么意思?套接字术语 - “阻塞”是什么意思?

我需要建立一个服务器组件(可能是一个Windows服务),它将接收数据,做一些处理并将数据返回给调用者。呼叫者可以等待答复,但我需要确保多个客户端可以同时呼入。

如果客户端1连接,我说10秒来处理他们的请求,2秒钟之后客户端2的呼叫会被阻塞吗?或者服务是否会开始在另一个线程上处理第二个请求?

总之,我的客户可以等待响应,但我必须能够同时处理多个请求。

+0

如果你真的需要使用原始套接字则有几十个用于在网络上的多线程服务器的例子,只是有一个谷歌。如果你不需要使用原始套接字,那么看看WCF。 – hyp 2011-04-21 08:57:51

回答

4

阻塞意味着您进行的调用(发送/接收)不会返回('阻塞'),直到底层套接字操作完成。

对于读取这意味着,直到收到一些数据或套接字已关闭。 写入意味着缓冲区中的所有数据都已发送出去。

为了处理多个客户端,为每个客户端启动一个新线程/将工作交给线程池中的一个线程。

连接的TCP套接字不能共享,因此无论如何它必须是每个客户端的一个套接字。

-1

您应该使用每个线程一个插座。阻塞套接字(同步)在返回之前等待响应。非阻塞(异步)可以查看是否收到任何数据,如果没有数据,可以返回。

+0

-1:第一句话是完全错误的(一般建议是不这样做,并使用异步操作来避免将线程绑定到套接字)。答案的其余部分是正确但含糊不清的(“响应”在这里有两个含义:API返回和来自套接字另一端的数据)。 – Richard 2011-04-21 09:03:16

+1

我不会推荐一个初学者以OP的方式开始异步操作。 '你应该每个线程使用一个套接字'对于新手来说是一个非常好的建议。但是,异步操作不会“偷看”。他们只是“睡觉”,直到操作系统告诉有什么已经到达插座。 – jgauffin 2011-04-21 09:07:52

0

阻塞调用将保持当前正在执行的线程,直到调用完成。

例如,如果你想从一个网络流中读取10个字节调用Read方法如下

byte[] buf = new byte[10]; 
int bytesRead = stream.Read(buf, 0, buf.Length); 

当前执行的线程将在读呼叫阻塞,直到10个字节已被读出(或ReadTimeout已过期)。

存在读写的异步变体以防止阻塞当前线程。这些遵循.NET中的标准APM模式。异步变体可以防止您必须向每个客户端发出一个线程(将被阻止),这会提高您的可伸缩性。

阻塞操作通常是那些发送或接收数据以及建立连接(即监听新客户端或连接到其他监听器)的操作。

0

为了回答您的问题,阻塞基本上意味着代码的函数或块内的控制停留(如(c)中++ ReadFile的),直到它返回,并且不移动到下面的代码本的代码块。 这可以在单线程或多线程上下文中。尽管在单个线程代码中阻止调用基本上是一场灾难。

解决方案:

在C#中解决这个问题,你可以简单地使用例如的BeginInvoke()和EndInvoke()在插槽方面异步方法,这不会阻止您的来电。这被称为异步编程方法。 你可以调用BeginInvoke()和EndInvoke(),无论是在一个委托或具体取决于异步方法你跟着来实现这个控制。

0

您可以使用该功能Socket.Select()

Select(IList checkRead, IList checkWrite, IList checkError, int microSeconds) 

同时检查可读性或可写多个插座。优点是这很简单。它可以从一个单独的线程来完成,你可以指定要等待多久,要么永远(-1微秒)或特定时间。而且你不必使你的套接字异步(即:让它们阻塞)。

它也适用于监听套接字。它会报告可写性。当有连接接受时。从实验中,我可以说,它还报告优雅断开连接的可读性。

这也可能是不一样快asyncrhonous插座。这对于检测错误也不理想。对于第三个参数,我没有太多用处,因为它没有检测到不正常的断开连接。