Recommended Posts

Hi all,
I've been having all sorts of issues with my IO Completion Port code for my MMORPG server (yes, yes, MMORPG, I know [smile]), and it's come to the point that I've just given up trying to debug it.
The code seems to get stuck in mutexes despite my best efforts to prevent that from happening, and is just generally a mess. The socket manager and the socket class are incredibly tightly coupled, which is A Bad Thing, I know. When it was working before, I had all sorts of problems with IO Completion Ports not sending the correct completion events, or WSAEventSelect and WSAWaitForMultipleEvents playing silly buggers.
I've uploaded the source code as a couple of MSVC 2005 workspace (There's the login server [which is basically a server], and the game server [which acts like a client to the login server]), and I've stripped as much redundant code as possible while still keeping the code relevant. Anway, here's the Link to the source code. It was originally based on This Article, but it's been modified quite heavily since then, particularly to include the event stuff for accepting and connecting, and to add the CSocket class for OOPyness
I'm looking for suggestions on how to tidy it up, or lay out the code in a way that doesn't suck, but is still nice and efficient. If anyone can manage to modify my code so it works, I'll love you forever [smile]
I hate debugging peoples code as much as anyone else, so I don't mind if nobody has a go at it. I'll just try re-writing it (again), and take things very slowly.
Finally, if anyone wants to use any of the code, feel free - you can use any of the code for anything you want, I don't care. If I manage to get this IOCP code working in a nice encapsulated way, I'll document it some more, add some more features (maybe), and then stick it on my website for anyone to download and use, so hopefully others can benifit from it.
Thanks in advance,
Steve

Link to post

Share on other sites

Original post by Evil SteveThe socket manager and the socket class are incredibly tightly coupled, which is A Bad Thing, I know.

I don't have IOCP code to post for you, but I can tell you that the socket implementation will quite likely be best buddies with the socket manager -- in fact, it would be quite reasonable to make the socket implementation be an inner class of the socket manager.

Coupling is, in itself, not bad. Coupling that's surprising, unnecessary, or spread all through public interfaces is what's bad.

The most frustrating part of IOCP (and overlapped I/O in general) is trying to write the API to allow cancellation and clean shutdown, as CancelIo() has some restrictions, and CancelIoEx() is only available in Windows Vista.

Share this post

Link to post

Share on other sites

Original post by hplus0603I don't have IOCP code to post for you, but I can tell you that the socket implementation will quite likely be best buddies with the socket manager -- in fact, it would be quite reasonable to make the socket implementation be an inner class of the socket manager.

Coupling is, in itself, not bad. Coupling that's surprising, unnecessary, or spread all through public interfaces is what's bad.

Hmm, I suppose. But the code is still getting pretty messy. I'm actually considering making CSocket a friend of CSocketManager and vice-versa, and getting all public functions to call a version in CSocketManager, then getting the socket manager to refer to the socket as a struct (I.e. get direct access to all it's member variables). That might be slightly cleaner.

Quote:

Original post by hplus0603The most frustrating part of IOCP (and overlapped I/O in general) is trying to write the API to allow cancellation and clean shutdown, as CancelIo() has some restrictions, and CancelIoEx() is only available in Windows Vista.

What restrictions are you referring to? The fact you have to call it from the same thread as the IO request was issued from? I used CancelIo at some point, but I seem to remember it started fighting with me, so I removed it (probably because of the thread problem)

Yup, that's exactly what I'm doing. Although general socket stuff is easy, it's just IOCP I'm strugling with. I'm fairly sure I understand how it all works, it's just trying to convert the principal into code that only exposes a single thread to the client code, and wraps the object up in a friendly manner (I.e. so the client can ask if the socket has data, instead of being told when it does - pull v.s push)

Quote:

Original post by kuphrynif you still want quick fix add breakpoints

Breakpoints don't work particularly well with 3 threads (5 on my machine [dual core]), logging is usually more effective (Which is also what I've done). Also, adding breakpoints causes the threading to go haywire and schedule differently. The mutex problems happen randomly too, so breakpoints wouldn't work.