Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Multi-threading the server doable?
#1
Quote:or maybe one thread per client connection
Your kidding right?
Reply
#2
Asrrin29 Wrote:
William Wrote:or maybe one thread per client connection
Your kidding right?

I have no idea, I'm new to anything to do with threads. I guess there would end up being a lot of threads on a per client basis. Maybe have three threads, one for the main loop, and two to handle connections? One for incoming one for outgoing?[/quote]

(stupid quote block prevention)

That would be pretty much the most basic kind of networking IO. Spawn a thread for each connection then do a blocking listen while sends are done in-line and also blocking (blocking isn't as much of an issue for sends). Its also probably one of the worst schemes for scalability. IOCP or asynchronous socket I/O would be a much better way to go. You could do your own thread pooling, but it'd become messy and troublesome very fast.

The scheme I am working with now has a thread for the main loop:

Code:
While (true)
   UpdateWorld();
   SocketManager.Heartbeat();
   Sleep();
Loop

UpdateWorld() would be self-explanitory. SocketManager.Heartbeat() tells all sockets to fork up their received data if they have any so it can be handled. It basically looks like:

Code:
HeartBeat() -> for every socket { Socket.Heartbeat(); }
Socket.Heartbeat()
{
   if (Socket.HasReceivedData)
   {
      OnReceive();
      FlushReceivedDataQueue();
   }
}

OnReceive() is an event trigger that the server is registered to. Its pretty much the same as calling the receive method, but through an event. Then the receive data queue is handled. This is still all in the update thread under the initial heartbeat() call.

All data is sent with a header of their size to prevent packet fragmentation. Whenever a socket receives a callback from the async receive, the data is pushed into a receive buffer (just an array twice the size the maximum allowed send size). Then the receive buffer is searched through for completed packets, which is quick and simple with keeping track of the highest write position. Completed packets are pushed into the ReceivedDataQueue where they wait until the Heartbeat().

Sent data, if a send is not already in progress, is just sent. A boolean keeps track of if a send is in progress or not to prevent trying to send multiple times from a single socket. A send request is also called when the send finishes if there is any queued data to send. This allows for sends to happen pretty much as fast as possible without having to poll the socket.

If a data send is already going and a send request is made, the data is used into a send queue. When the next in-progress send finishes, data is removed from the queue until either the queue is emptied or the buffered packet is full. This provides for a nice and easy buffering system.

On a basic view, its a pretty simple system. Sends and receives are completely separated and, using a few locks (which unfortunately VB6 doesn't have so you'd probably have to do some kind of spin-wait, which sucks), theres no threading issues and you don't even have to think about threading when you're outside of the networking class.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)