Async TCP/IP with a Console App
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?
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.
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.
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%.
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%.
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
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
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
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
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.
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]
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]
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement