Writing an overlapped I/O server app
I'm trying to write, yep, you guessed it, an MMORPG client-server app suite. I program for fun, not for a living. Yes I do realize everyone and their mom tries to make an MMORPG. Regardless, I'm looking for some bright minds to shed some light on this issue of mine. I've been reading over all about Window Sockets, or just Winsock in general, (I'm amazed how handy my CCNA knowledge is in this area) but I'm trying to figure out the best way to write a server application that will support many many connections at once. I don't know if any of you have ever played Ragnarok Online (www.ragnarokonline.com), but it's been the only MMORPG I can stand playing, and quite fun too. Frankly, I hate the MMORPG genre. There's an open source project for creating a server for the game, and you illegally modify the clients to connect to the servers. Well after hosting this server many times and even tweeking and recompiling the source, I've found out many interesting ideas on how it's all done. I'm not a programming master or anything, though I'd say I'm pretty compitent with C++, thus I did not fully delve into the server project to figure out how it all works. Here's what I propose: A client will connect to the server, the first server application will authenticate the user and pass them on to the game-server selection(if there are multiple worlds), then character selection screen for that world. This will be running off a MySQL backend storing the user's information. After the user passes that portion, they will be connected to the actual in-game server that manages the monsters, in-game transactions, player movement synchronization, etc... This is where I need the help. The model I've seen from Ragnarok Online is that you have a server that manages each map, generally you can have anywhere from 1-1000 players on each map. When you move to the exit/warp gate/whatever you want to call it, the server switches you over to a next server that manages that map. That's all fine and dandy, if you have a thousand servers, public IPs, and bandwidth galore. I suppose I could have pre-defined areas of maps that the server manages as 1 entity, then you could pass it off to another management server that runs another zone on a different port #, or server if you have the resources. Alright, finally to the issue. I'm not sure how many people I should theoretically expect. Yes, I know, my game probably will never make it, but I want some real-world experience in the area. Should I stick with simple asynchronous sockets that support up to ~100 connections or should I move into overlapped I/O. If overlapped I/O (http://tangentsoft.net/wskfaq/articles/io-strategies.html), I really don't have any idea how to impliment something like that. I was hoping asynch sockets would support around 300 connections, which would probably cover my bases. I plan to make my server modular so it can pass off to another server by IP and/or port just in case I were to expand the infrastructure accordingly. Else the localhost and different port number would suffice. And one last thing, should I be using UDP in this situation? Reading over some articles makes it seem like it's a bad idea to use TCP in this situation for some reason. I hope my rambling post made some sort of sense. Winsock seems to be the most difficult API I've seen yet, even OpenGL/GLUT/SDL/MySQL APIs aren't this bad in my opinion. Perhaps it is the lack of documentation. Thank you!
-Conrad
If you want to talk about high performance windows server software, then there's really no way to go about it except I/O Completion Ports.
I've done some hefty work in the area (about 2.5 - 3 years ago), and unfortunately am terribly fuzzy about it.
Remember, Google is your friend! There's some great resources on IOCP out there, and some decent libs if you look hard enough
I've done some hefty work in the area (about 2.5 - 3 years ago), and unfortunately am terribly fuzzy about it.
Remember, Google is your friend! There's some great resources on IOCP out there, and some decent libs if you look hard enough
daerid@gmail.com
I think I may be getting in over my head here. I'm not familiar much with win32 API beyond the fact that you create a window class and that system messages are a key feature. On top of that, I'm not really solid on Winsock, let alone anything about application multithreading.
I will try to search around google for some wrappers/libs about IOCP, but I don't know how much good it'll do me if I don't know multithreading. Maybe you could recommend a good wrapper/lib for it, or maybe I should just stick with a wrapper/lib for asynch connections?
I will try to search around google for some wrappers/libs about IOCP, but I don't know how much good it'll do me if I don't know multithreading. Maybe you could recommend a good wrapper/lib for it, or maybe I should just stick with a wrapper/lib for asynch connections?
-Conrad
I think this was a bad idea trying to get into IOCP. I'm now reading up on threading with the win32 API and there's tons of words and functions I don't know about handling classes/threads in win32.
What if I simplify my theory into something more reasonable for my situation... With asynch sockets, do I still need multithreading to handle the incoming requests while the server does other processing in the background for the world? Or can I just do a giant loop of processing then next time around check the asynch sockets again?
I like the idea of using UDP with a seperate reliability component to it, probably would save bandwidth and some resources on both ends. Refresh my memory though, does UDP work with streams or would I just be spitting out a datagram packet(s) destined to an IP/port when need be?
My idea is just to have the server(s) running multiple instances of the same in-game world managment application managing different maps and link the client to different IP/ports for the managment of that map, securely. That way I won't be doing tons of crazy multithreading I know nothing about when windows can just do application-threading and manage it itself. My test server is a 3.0GHz Xeon, 1GB DDR2, on a cable 3mbps down/256k up line. Maybe I should have sprung for the extra CPU if I was going to get into multithreading. :/
[EDIT]
I found a great setup for IOCP from this place:
http://www.codeproject.com/internet/SimpleIOCPApp.asp
I'm looking over the whole setup now, after reading a little multithreading theory and code as well as winsock information all day, it make some sense. Is that enough for me to use to start threading an application appropriately for my needs? (File: Download multithreaded server using IOCP (new overlapped I/O implementation) - 6.78 Kb)
What if I simplify my theory into something more reasonable for my situation... With asynch sockets, do I still need multithreading to handle the incoming requests while the server does other processing in the background for the world? Or can I just do a giant loop of processing then next time around check the asynch sockets again?
I like the idea of using UDP with a seperate reliability component to it, probably would save bandwidth and some resources on both ends. Refresh my memory though, does UDP work with streams or would I just be spitting out a datagram packet(s) destined to an IP/port when need be?
My idea is just to have the server(s) running multiple instances of the same in-game world managment application managing different maps and link the client to different IP/ports for the managment of that map, securely. That way I won't be doing tons of crazy multithreading I know nothing about when windows can just do application-threading and manage it itself. My test server is a 3.0GHz Xeon, 1GB DDR2, on a cable 3mbps down/256k up line. Maybe I should have sprung for the extra CPU if I was going to get into multithreading. :/
[EDIT]
I found a great setup for IOCP from this place:
http://www.codeproject.com/internet/SimpleIOCPApp.asp
I'm looking over the whole setup now, after reading a little multithreading theory and code as well as winsock information all day, it make some sense. Is that enough for me to use to start threading an application appropriately for my needs? (File: Download multithreaded server using IOCP (new overlapped I/O implementation) - 6.78 Kb)
-Conrad
Quote:
That's all fine and dandy, if you have a thousand servers, public IPs, and bandwidth galore.
Welcome to the world of the MMO. If you think that you can't really deal with that, then you probably want to do something else. It's sort of like car racing: you need a racing car, with a roll cage, and five point harness, and a trailer, and all the rest. If you can't afford all those things, you probably want to find another hobby. Or sit on the sidelines as a fan, instead of doing the actual driving.
You want to scale to 300 people. I understand it's the intellectual challenge that drives you. Do you actually have the bandwidth to serve 300 people? Assuming they each use 2 kB/sec on average (which is pretty low by modern standards), that's four bonded T1 connections of upstream from your server. If you don't have this kind of bandwidht, do you REALLY have to worry about scalability to that level?
I would stay away from asynchronous sockets, they are low performance, sometimes unreliable, and may stop out at 64 connections because of some internal Windows limitation. Instead, I would write the first pass using select() (you can increase the number of supported connections by increasing the size of the fd_set, see the Forum FAQ). Only when select() is shown in practice to start being a performance problem would I re-work that part to something faster.
Last, if it is the intellectual challenge you're after, then why balk at IOCP? It's not that hard a model, and MSDN has reasonable documentation for it (as well as some tutorials on codeproject and other net destinations).
Whatever you choose, good luck!
enum Bool { True, False, FileNotFound };
I do have plenty of boxes laying around if I really do need to use more servers. Verizon is installing FiOS in my area, and I'm getting 2mbps upload bandwidth. 300*~2kbps = 600kbps, well within my range. So the bandwidth isn't a problem much anymore. Even if the game somehow got big, I have some good backend funding to put together a nice fat pipeline for the servers, though I'd probably need a little monthly fee to pay support it. On top of that, I only need 1 public IP, I'll just use NAT and port forwarding to manage the multiple servers and just forward the client to the appropriate map server's port.
That's just theoretical, this is pretty much for fun and a challenge on my part to myself. After reviewing the IOCP model it really doesn't look that difficult of a task to do, I think I'll go ahead with create a prototype client-server situation and see how that turns out. Also, MSDN documentation scares me sometimes. :)
Thank you guys! Time and time again this community shows me how great they really are.
That's just theoretical, this is pretty much for fun and a challenge on my part to myself. After reviewing the IOCP model it really doesn't look that difficult of a task to do, I think I'll go ahead with create a prototype client-server situation and see how that turns out. Also, MSDN documentation scares me sometimes. :)
Thank you guys! Time and time again this community shows me how great they really are.
-Conrad
Quote:
300*~2kbps = 600kbps
I was suggesting 2 kBps, which turns into 16 kbps (plus framing overhead). For 300 users, that's 4.8 Mbps -- and you typically want some extra slop, to avoid congestion and "spiral of death" situations. Thus, the recommendation for 4 bonded T1 circuits.
Anyway, sounds like you have a path forward. Good luck! And don't let that MSDN documentation scare you -- it's really the best source of information on general Windows programming.
enum Bool { True, False, FileNotFound };
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement
Recommended Tutorials
Advertisement