开发者

Super High Performance Socket Server - Implementation Details

开发者 https://www.devze.com 2023-04-13 07:57 出处:网络
I\'ve done my research and I know the best way to implement a high performance socket server is generally as follows: use async socket operations (specialized SocketAsyncEventArgs/Operations for best

I've done my research and I know the best way to implement a high performance socket server is generally as follows: use async socket operations (specialized SocketAsyncEventArgs/Operations for best performance) and on the async callback, push the request to a processing queue that is tended by a pool of threads.

My questions for this processing model - to have the greatest performance:

1) when should the "End" operation of the socket be called (e.g. EndAccept or EndReceive)? should this be called on the callback thread (IOCP) before queuing the request? or called when the request gets taken out from the queue and gets processed (worker thread)?

2) this question depends on the answer to #1. when should the next "Begin" operation be called? should we call it before we call EndOperation even or should we call it immediately right after EndOperation (before queuing/processing request)?

3) can the processing queue simply be the .NET threadpool? what advantages/drawbac开发者_StackOverflowks would using the .NET threadpool vs. rolling out your own synchronized processing queue?

Any help is greatly appreciated.


1) The EndReceive should be the first thing you do in the async callback. In fact, you can't do much of anything else in the callback until you've called EndReceive, because that's what gives you the data that was received. See the example at Socket.EndReceive.

Same thing goes for EndAccept, since it gives you the socket that you'll be communicating with.

2) You should call BeginAccept as soon as possible after the EndAccept. Otherwise you risk missing connection requests if your accept callback takes too long to process. Of course, if your accept callback is taking a long time to do anything, you're doing it wrong. Again, same thing goes for BeginReceive: call it as soon as you can after EndRead, to avoid losing data. Or, if your communications protocol is a request/response model, where the client expects a response before sending any more data, you could wait to call BeginRead until after you've sent the response.

3) The processing could be the .NET thread pool, although if you're going to use that you should look into using the Task Parallel Library. The advantage of using the TPL is that it's very much "fire and forget," or perhaps "fire and it'll call back when done." The disadvantage of using the TPL is that it's more difficult for your application to know what tasks are pending. If you create your own synchronized processing queue, you always know what jobs are pending and you have the potential of examining the queue, canceling jobs, etc. If you want to do that with the TPL, you end up creating a collection of tasks that you have to manage, since there's no way to get the the list of pending tasks.

But if you don't need to see the pending tasks, then TPL should work well.

The related questions here have some good information.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号