简体   繁体   English

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

[英]Asynchronous server socket multiple clients

I have been working with the following code published on msdn:我一直在使用 msdn 上发布的以下代码:

http://msdn.microsoft.com/en-us/library/fx6588te.aspx 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?如果客户端 A 和 B 同时连接会发生什么?

  • 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?如果客户端 A 连接并且处理其请求需要 5 秒,如果客户端 B 稍后连接,它是否必须等待客户端 A 完成才能开始处理?

  • Or will client A and client B's requests be handled concurrently?还是会同时处理客户端 A 和客户端 B 的请求?

I have done some testing with this by putting Thread.Sleep(n) commands in between the receive/send data in the socket listener code.我通过在套接字侦听器代码中的接收/发送数据之间放置 Thread.Sleep(n) 命令对此进行了一些测试。 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.然而,套接字总是在同一个线程 id 上处理它们——这让我相信它实际上并没有同时发生。

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?特别是考虑到微软的描述,这个应用程序在等待新连接时根本不会阻塞——这是否意味着它可以处理并发连接?

[Update 2014]: It seems that the example has been modified since this answer was posted, as noted in this thread . [2014 年更新]:自发布此答案以来,该示例似乎已被修改,如该线程中所述。 The MSDN example now handles multiple incoming connections properly. MSDN 示例现在可以正确处理多个传入连接。 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.在进行套接字通信时,基本上所有传入连接都有一个侦听器套接字,每个连接的客户端都有多个处理程序sockets。

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 ).此行告诉侦听器在连接新客户端时调用AcceptCallback方法(新连接回调)。 That method is the one which should do its work quickly, since it blocks other incoming connections.该方法应该快速完成其工作,因为它会阻止其他传入连接。

Creating dedicated handler sockets创建专用处理程序 sockets

That is also why AcceptCallback must immediately create a dedicated "handler" socket with its own background data callback method ( ReadCallback ):这也是为什么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

From that moment on, ReadCallback method is invoked whenever some data is received by your newly connected client.从那一刻起,只要新连接的客户端收到一些数据,就会调用ReadCallback方法。

Also, before returning, AcceptCallback needs to call listener.BeginAccept again, to continue listening to new incoming connections:另外,在返回之前, 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);

This part is omitted from the MSDN example, meaning it can only receive a single connection.这部分在 MSDN 示例中被省略,意味着它只能接收一个连接。

Receiving data接收数据

As soon as you get a packet of data from your client, ReadCallback method will be invoked.一旦从客户端获得数据包,就会调用ReadCallback方法。 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).所以,在这个数据回调方法中,你需要读取并处理接收到的数据,然后再次调用相同的BeginReceive方法(同样,使用ReadCallback作为它的数据回调方法)。

[Edit] [编辑]

The problem with MSDN example is that it allows connection of only a single client ( listener.BeginAccept is called only once). MSDN 示例的问题在于它只允许连接单个客户端( listener.BeginAccept仅调用一次)。 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.要允许多个并发连接,您需要使用handler.BeginReceive创建一个接收套接字,然后调用listener.BeginAccept开始监听新客户端。

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.挂起连接的最大数量可以在listen() API 中以编程方式定义,在本例中只是“listener.Listen(100)”。 Having had this as 100 here, the socket 'listener' can have 150 (=2*100/2) pending connections in the listen queue.在这里设置为 100,套接字“侦听器”在侦听队列中可以有 150 (=2*100/2) 个挂起的连接。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM