套接字术语 - “阻塞”是什么意思?

时间:2011-04-21 08:50:25

标签: c# sockets tcp

在C#中讨论套接字编程时,阻塞这个术语是什么意思?

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

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

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

6 个答案:

答案 0 :(得分:4)

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

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

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

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

答案 1 :(得分:0)

这意味着您不能在当前正在执行的线程上使用套接字。

它与szerver方面无关。 这意味着线程在等待套接字响应时暂停。

如果您不想暂停,请使用异步方法。

了解详情:http://www.developerfusion.com/article/28/introduction-to-tcpip/8/

答案 2 :(得分:0)

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

例如,如果您希望从网络流中读取10个字节,请按如下方式调用Read方法

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

当前正在执行的线程将在Read调用上阻塞,直到读取了10个字节(或ReadTimeout已过期)。

存在读取和写入的异步变体以防止阻塞当前线程。这些遵循.NET中的标准APM模式。 Async变体可以防止您必须为每个客户端处理一个线程(将被阻止),这会增加您的可伸缩性。

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

答案 3 :(得分:0)

为了回答你的问题,阻塞基本上意味着控件保留在一个函数或代码块(例如c ++中的readfile())中,直到它返回并且不会移动到此代码块之后的代码。 这可以是单线程或多线程上下文。虽然在单线程代码中进行阻塞调用基本上是一种灾难。

解决方案:

要在C#中解决这个问题,您可以简单地使用异步方法,例如套接字上下文中的BeginInvoke()和EndInvoke(),它们不会阻止您的调用。这称为异步编程方法。 您可以在委托或控件上调用BeginInvoke()和EndInvoke(),具体取决于您遵循的ASYNCHRONOUS方法来实现此目的。

答案 4 :(得分:0)

您可以使用Socket.Select()

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

检查多个套接字的可读性或可写性。优点是这很简单。它可以从单个线程完成,您可以指定要等待的时间,永久(-1微秒)或特定持续时间。并且你不必使你的套接字异步(即:阻止它们)。

它也适用于侦听套接字。它将报告可写性。当有连接接受时。通过实验,我可以说它还报告了优雅断开连接的可读性。

它可能不如异步套接字快。它也不是检测错误的理想选择。我对第三个参数没什么用处,因为它没有检测到不合适的断开。

答案 5 :(得分:-1)

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