Sign in to follow this  

Async TCP/IP with a Console App

This topic is 3932 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Background: I'm writing a game server that could handle over 1000 users. Unfortunatly, my current socket implementation is using blocking sockets with threads (as a quick hack). When I start to stress test my server, things get really gross (as expected). Question: Is it possible to use async TCP/IP with a console app, or do I need to create a real Windows window and use their event model?

Share this post


Link to post
Share on other sites
I don't understand what you mean by network thread.

I'm thinking I have to switch over to the windows event pump because, the winsock async network calls want a window handle for returning events to me.

Share this post


Link to post
Share on other sites
Asyncronous is usable on a Windows application only.

In a console app you would have to look into non-blocking sockets.

People often get confused with non-blocking and asyncronous. They are greatly different.

Async uses windows messages to get the job done allowing you to free up CPU time.

Non-blocking loops continuously boosting your CPU usage to 100%.

Share this post


Link to post
Share on other sites
In a console application you can use non-blocking sockets.

What exactly "async" is depends on your point of view. WSAAsyncSelect should, in my opinion, never be used for anything as it involves USER32.DLL in a wholly non-user-interface operation. Windows user interface messages are designed for users clicking things, which is not what you want. It's basically a hack which was designed for win16 cooperative multitasking.

You can quite adequately use as many sockets in non-blocking mode as you like, in a console app without requiring WSAAsyncSelect, however, you will need to use some other platform-specific synchronisation mechanism instead.

I believe that on win32 the mechanism you need to use is called "I/O completion ports", which will allow you to create an event which is triggered by some specified activity, you can block on that event then find out what happened. I don't know the details.

Of course select() is still a simple option with many examples, but it has the following problems:
- Very inefficient on large (1000s) numbers of sockets (every time a single thing happens, you have to scan and repopulate an array-like structure)
- You can't wait for a socket event *OR* something else (Except a timeout) easily in win32 with select (On Unix you can)

Non-blocking loops do *NOT* boost your CPU time to 100% unless you use busy-waiting, which I don't recommend. Note that a non-blocking loop might be a sensible implementation for a game client which is looping on some timer doing game logic and rendering etc as well, but probably isn't for a game server.

Mark

Share this post


Link to post
Share on other sites
Thanks MarkR!

I had explored all the other options except I/O Completion Ports. You're right, glomming async ports into the windows event spiggot seemed like a huge hack to me as well.

Lonewolff, I had looked seriously into non-blocking ports via select. Even though everyone said it was a step up from threaded blocking call, it was still very lame when you have a lot of connections. Hey, even if I were to poll, I definately would have shoved a sleep(0) call in there somewhere.

I did find a asynch class last night that didn't involve MFC, but when I started to try to get it to compile, I noticed it had a thread lurking in its members. One thread per socket was a step backwards even if it was async. I sort of threw up my hands and went to sleep.

I'll try these I/O Completion Ports next. I founds a nice looking link here.
http://www.microsoft.com/technet/sysinternals/information/IoCompletionPorts.mspx

Share this post


Link to post
Share on other sites
Why not use WSAEventSelect??? Works similar to WSAAsyncSelect, but does not require a window msg queue, instead it triggers kernel event objects. I use it in a console app, works quite nicely, alot easier to use IMHO than IO-completion ports.

Share this post


Link to post
Share on other sites
I'm trying to figure the difference between I/O Completion ports and WSAEventSelect.

I'm beginning to think that WSAEventSelect is a single threaded version of I/O Completion Ports. Is this right?

Edit: I found a really great article on overlapped I/O with worker threads here: http://www.codeproject.com/internet/SimpleIOCPApp.asp

[Edited by - RWThurman on March 8, 2007 1:56:17 PM]

Share this post


Link to post
Share on other sites
I/O-completion ports and WSAEventSelect are different animals. IOCP also allows the use of an internal thread pool. So esentially u ask it to run your function and it figures out the threading issues, its actually a bit more complicated than that but that is the jist. According to M$ IOCP is the only scalable solution for large amounts of connecting users, but somehow i doubt that considering alot of high end apps, that run on windows, (such as Apache) dont, as far as i know, use them.

I use WSAEventSlect with around 50 connections, but i make sure to multiplex multiple connections on only a few threads. I might look at how Apache does this for 1000s of connections.

Share this post


Link to post
Share on other sites
Asynchronous sockets are not high performance, and I believe there is a limitation of 63 sockets max in the async select code (related to the NT kernel 64-object limitation for WaitForMultipleObjects, I believe).

Your options include non-blocking sockets, or select(), or using I/O completion ports.

Share this post


Link to post
Share on other sites
Quote:
Original post by RWThurman
Background:
I'm writing a game server that could handle over 1000 users. Unfortunatly, my current socket implementation is using blocking sockets with threads (as a quick hack). When I start to stress test my server, things get really gross (as expected).

Question:
Is it possible to use async TCP/IP with a console app, or do I need to create a real Windows window and use their event model?



With non-blocking and a tight input loop (using the console routine that tests if a key was hit). It depends how extensive the input needs to be for the control inteface on the console App -- if you can limit it to single char driven menus its fairly simple -- no long waiting at a prompt to get input tgat would stall the network processing. Switch() driven FSM if its a multi-tiered menu. As someone else mentioned you could also have a network thread which is a little more complicated.

Share this post


Link to post
Share on other sites
Wow! I got the IO completion system up and running. I thought this whole thing was going to a big locking nightmare. In the end, I was able to avoid using any mutexs or spinlocks. I was able to replace the old system with the new async/overlapped system too.

Share this post


Link to post
Share on other sites

This topic is 3932 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this