Advertisement

multi-threaded problem

Started by March 14, 2003 07:59 AM
3 comments, last by mtaber 21 years, 10 months ago
Ok, let''s see.. where to start. I''m writing a multi-threaded TCP socket server using winsock. Uses stream connections and basically all of the data being sent is text with a separation character and each ''packet'' is terminated by a carriage return line feed. It seemed to work fine for the longest time. The past couple of days, it''s been having a lot of problems and it seems that the packets aren''t being sent out properly anymore. I have a PacketMessage class that inherits from Packet. Reason being, a Packet is sent to the client, but the PacketMessage is used after a player has logged in by setting central variables that tell the server who to send the Packet to. If I print out the packet according to it''s parameters, I''ll get something like this: command=LOBBYCHAT parameter1=mike parameter2=nice fullcommand=LOBBYCHATÿmikeÿniceÿ where fullcommand is actually the entire data stream returned by a different function. The first 3 lines are printed by one function, the next is printed by another that calls GetCommand(). Uses the exact same type of loop. *Shouldn''t* be a problem, since the code is quite nearly the same. Just prints different things. Other times, it will return something like this: command=LOBBYCHAT parameter1=mike parameter2=nice fullcommand=LOBBYCHATÿmikeÿniceÿOB See the difference? At that point, the OB overwrites the carriage return/line feed that I''m using to separate the ''packets'' in the stream. The ÿ character is the data separator. The only difference between the first three lines and the last one is that they''re called by different functions, all of which use local variables and return values (not pointers or references. Now, what I want to know is this. I''m using an STL list (for which all of my access commands are threadsafe) and I''m also using the string class using namespace std. The PrintPacket() function is called by a number of different objects, but it''s not a global function. It''s part of the PacketMessage class. Is it possible that the returned string (just returning string, not a pointer) is being partially overwritten by some other call to PrintPacket() for another object? I would think that each thread in which the packet is declared would have its own stack space and any local variables declared would use only that stack space, but at this point I''m clueless as to what''s going on. Should I pass in a pointer to a string for each of these functions and use that as opposed to local variables within the PrintPacket() and GetCommand() functions?
Looking for an honest video game publisher? Visit www.gamethoughts.com
Shameless plug: Game Thoughts
try memset() before you write to the packet ...
Advertisement
Well, it's declared as a string, not a character array. The Packet class is declared as a 'string commandType;' and a string parameters[15];' so that I have 15 possible parameters for any given packet. Each and every time that I create the packet, I reset the commandType and all of the elements in the parameters array to = "". That should clear all of them.

Should I be calling memset() on something else? One other thing is that I'm using multiple blocking sockets on the same port and each connection request spawns a new thread. That connection is kept active and the thread is listening on it all the time. So, I have a session thread listening on that socket at all times.

The main thread is the only one that writes to any socket and the session thread is the only one that reads from it. Could that be the problem? I have two threads running that read from and write to the same socket at about the same time so some of the data is getting overwritten? Should I have a critical section set up so that a socket can be read from or written to, but not both at the same time? I wouldn't have thought it would be an issue, especially since it's the packet message itself that seems to be getting corrupted, and that is stored in a thread safe container.


Looking for an honest video game publisher? Visit www.gamethoughts.com

[edited by - mtaber on March 14, 2003 11:24:59 AM]
Shameless plug: Game Thoughts
Before you get too deep into writing your own multi-threaded socket impelementation, take a look at IO Completion Ports. This is assumeing you are writing againt Win32 other than Win9x.

It shouldn''t matter if you are reseting your recieve or send buffer between calls to send or receive since the winsock implementation should just write over the posted buffer.
I think that part of the problem had to do with the fact that I was getting the size of some of the lists I''m using for passing messages back and forth between the sessions, but I wasn''t locking the list with a critical section before getting that count. The problem is that I remove a message before I send it. But calling .size of the list creates a list iterator. If that function is pre-empted by the OS while calculating the size, it will flake out because the other threads tend to add or delete messages from the list.

I think that''s why it was flaking out, but only when a large number of messages were coming in all at about the same time. I''ve since reworked it a bit and I wrote a simulator to test it. It seems to be able to handle a hundred connections fairly easily. Now, to scale it up to a thousand.
Shameless plug: Game Thoughts

This topic is closed to new replies.

Advertisement