异步服务器套接字多个客户端

发布于 2024-11-03 19:19:37 字数 605 浏览 0 评论 0原文

我一直在使用 msdn 上发布的以下代码:

http://msdn.microsoft.com/en- us/library/fx6588te.aspx

我知道服务器应用程序在等待新客户端时不会被阻止。

但是,这个应用程序(甚至套接字)可以处理多个并发请求吗?

  • 如果客户端 A 和 B 同时连接会发生什么?

  • 如果客户端 A 连接并且处理其请求需要 5 秒,如果客户端 B 一秒后连接,它必须等待客户端 A 完成才能开始处理吗?

  • 或者客户端A和客户端B的请求会同时处理吗?

我通过在套接字侦听器代码中的接收/发送数据之间放置 Thread.Sleep(n) 命令来对此进行了一些测试。然后我可以向套接字发送多个请求,并且它们似乎已得到处理。然而,套接字总是在相同线程ID上处理它们——这让我相信它实际上并不是同时发生的。

特别是考虑到微软的描述,该应用程序在等待新连接时不会阻塞 - 这是否意味着它可以处理并发连接?

I have been working with the following code published on msdn:

http://msdn.microsoft.com/en-us/library/fx6588te.aspx

I understand that the server application is not blocked whilst the application is waiting for new clients.

However can this application (or even sockets) for that matter handle multiple concurrent requests?

  • What would happen if client A and B connected at the same time?

  • If client A connects and the handling of its request takes 5 seconds, if client B connects a second later must it wait for client A to finish before its processing can start?

  • Or will client A and client B's requests be handled concurrently?

I have done some testing with this by putting Thread.Sleep(n) commands in between the receive/send data in the socket listener code. I can then send multiple requests to the socket and they appear to be handled. However the socket always handles them on the same thread id - which makes me believe that it isnt actually happening concurrently.

Especially given the description by microsoft that this app simply doesnt block whilst awaiting for new connections - does that mean it can handle concurrent connections?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

烟柳画桥 2024-11-10 19:19:37

[2014年更新]:自从发布此答案以来,该示例似乎已被修改,如此中所述线程。 MSDN 示例现在可以正确处理多个传入连接。无论如何,这里描述的一般方法是正确的,也许它可以提供额外的说明。


在进行套接字通信时,基本上有一个用于所有传入连接的侦听器套接字,以及用于每个连接的客户端的多个处理程序套接字。

侦听传入连接

当您开始侦听端口时,您将创建一个带有传入连接回调方法的套接字(这是引用您提到的示例)。这是该端口号的唯一侦听器套接字

listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);

这一行告诉侦听器在连接新客户端时调用 AcceptCallback 方法(新连接回调)。该方法应该能够快速完成工作,因为它会阻止其他传入连接。

创建专用处理程序套接字

这也是为什么AcceptCallback必须立即创建一个专用“处理程序”套接字及其自己的后台数据回调方法(ReadCallback):

// inside AcceptCallback, we switch to the handler socket for communication
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
    new AsyncCallback(ReadCallback), state); // fired on a background thread

从那一刻起,只要新连接的客户端收到一些数据,就会调用 ReadCallback 方法。

另外,在返回之前,AcceptCallback需要再次调用listener.BeginAccept,以继续侦听新的传入连接:

// this is the same server socket we opened previously, which will now 
// continue waiting for other client connections: it doesn't care about
// the actual data transmission between individual clients
listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);

这部分在MSDN示例中被省略,意味着它只能接收单个连接。

接收数据

一旦您从客户端收到数据包,ReadCallback 方法就会被调用。因此,在这个数据回调方法中,您需要读取并处理接收到的数据,然后再次调用相同的 BeginReceive 方法(再次使用 ReadCallback) code> 作为其数据回调方法)。

[编辑]

MSDN 示例的问题在于它仅允许连接单个客户端(listener.BeginAccept 仅被调用一次)。要允许多个并发连接,您需要使用handler.BeginReceive创建接收套接字,然后调用listener.BeginAccept开始监听新客户端。

[Update 2014]: It seems that the example has been modified since this answer was posted, as noted in this thread. The MSDN example now handles multiple incoming connections properly. Anyway, the general approach described here is correct and perhaps it can provide additional clarification.


When doing socket communication, you basically have a single listener socket for all incoming connections, and multiple handler sockets for each connected client.

Listening to incoming connections

When you start listening to a port, you create a socket with a callback method for incoming connections (this is referencing the example you mentioned). That's the one-and-only listener socket for that port number:

listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);

This line tells the listener to invoke the AcceptCallback method whenever a new client is connected (new connection callback). That method is the one which should do its work quickly, since it blocks other incoming connections.

Creating dedicated handler sockets

That is also why AcceptCallback must immediately create a dedicated "handler" socket with its own background data callback method (ReadCallback):

// inside AcceptCallback, we switch to the handler socket for communication
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
    new AsyncCallback(ReadCallback), state); // fired on a background thread

From that moment on, ReadCallback method is invoked whenever some data is received by your newly connected client.

Also, before returning, AcceptCallback needs to call listener.BeginAccept again, to continue listening to new incoming connections:

// this is the same server socket we opened previously, which will now 
// continue waiting for other client connections: it doesn't care about
// the actual data transmission between individual clients
listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);

This part is omitted from the MSDN example, meaning it can only receive a single connection.

Receiving data

As soon as you get a packet of data from your client, ReadCallback method will be invoked. So, inside this data callback method, you need to read and process the received data, and then invoke the same BeginReceive method again (again, with ReadCallback as its data callback method).

[Edit]

The problem with MSDN example is that it allows connection of only a single client (listener.BeginAccept is called only once). To allow mulitple concurrent connections, you need to create a receive socket using handler.BeginReceive, and then call listener.BeginAccept to start listening to new clients.

无人问我粥可暖 2024-11-10 19:19:37

每个套接字都有一个与其关联的监听队列。这将具有待处理/部分接受的传入连接。挂起连接的最大数量可以在listen() API中以编程方式定义,在本例中它只是“listener.Listen(100)”。此处设置为 100,套接字“侦听器”在侦听队列中可以有 150 (=2*100/2) 个待处理连接。

Every socket will have a listen queue associated with it. This will have the pending/partially accepted incoming connections. The max number number of pending connections can be defined programmatically in listen() API, which is nothing but 'listener.Listen(100)' in this example. Having had this as 100 here, the socket 'listener' can have 150 (=2*100/2) pending connections in the listen queue.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文