1

I have a WinSock server and I was wondering how to make it multi-threaded. I have used threads before and I understand what they do. But I'm not sure how to use them with my server code. So here it is:

main.cpp

/* This is our Server */

//Includes
#include "Functions.h"

//Main function
int main(){
    DLLVERSION = MAKEWORD(2,1);
    answer = WSAStartup(DLLVERSION, &wsaData);
    sConnect = socket(AF_INET, SOCK_STREAM, NULL);
    addr.sin_addr.s_addr = inet_addr(HostIP);
    addr.sin_family = AF_INET;
    addr.sin_port = htons(PORT);
    sListen = socket(AF_INET, SOCK_STREAM, NULL);
    bind(sListen, (SOCKADDR*)&addr, sizeof(addr));
    listen(sListen, SOMAXCONN);

    //Listening for clients
    for(;;){
        Print("Waiting for incoming connections");
        //If a connection is found
        if(sConnect = accept(sListen, (SOCKADDR*)&addr, &addrlen)){
            Print("Connection found!");
            Send("Hello!");
        }
    }
}

How would I make this server multithreaded?

I tried using CreateThread(); but as soon as another thread is created, the last thread ends for some reason. Can anyone help?

MSalters
  • 173,980
  • 10
  • 155
  • 350
  • its not necessary to write a server that handles multiple request with threads. You could use `select()`. Is this a requeriment? – Sebastian Aug 29 '13 at 03:55
  • @Sebastian I am coding a game server, is it necessary to do so with a game server? – user2635579 Aug 29 '13 at 05:26
  • It's not theoretically necessary, but practically yes. BTW it's probably not a good idea to have one thread per request either. Look into threadpools. – MSalters Aug 29 '13 at 09:48
  • @MSalters What do you recommend i do for a game server? Because since it's going to have multiple players online at once, don't i need to be accepting connections like every millisecond? – user2635579 Aug 29 '13 at 18:49
  • @user2635579: Not really. A typical game takes thousands of milliseconds to load. Just send the connection request early, and your users won't notice even if the accept took half a second. – MSalters Aug 30 '13 at 07:44

2 Answers2

0

You can use select (or poll too if you are on POSIX land) to wait on the server socket.

select: Using select() for non-blocking sockets

You main server process listens on the socket and as soon as a request comes in you spin off a thread (from a thread pool) which interacts with the client. That's the gist of it. Windows has a thread pool to use, take a look at the QueueUserWorkItem Win 32 call http://msdn.microsoft.com/en-us/library/windows/desktop/ms684957%28v=vs.85%29.aspx

Community
  • 1
  • 1
Csaba Toth
  • 10,021
  • 5
  • 75
  • 121
0

You probably want a few things:

  • Sockets are text streams, but you probably uses messages. You probably want a few threads which each listen to a number of sockets. When they do have a message, dispatch that message, generally to another thread.
  • In Windows, you'd use WSAWaitForMultipleObjects() to listen to multiple sockets.
  • You indeed want a thread to deal with new incoming connections. One should be enough. Each new connection should be sent to added to one of those listener threads.
  • Welcome messages can be sent by the listener thread as it picks up the incoming connection.
  • You can use a semaphore to keep track of the number of incoming connections not yet picked up by listening threads. Add the semaphore to WSAWaitForMultipleObjects, and the first idle listening thread will pick up the incoming connection. This balances the load across threads.
MSalters
  • 173,980
  • 10
  • 155
  • 350
  • + on Windows he can have a ready to go thread pool if he uses the `QueueUserWorkItem` Win 32 API http://msdn.microsoft.com/en-us/library/windows/desktop/ms684957%28v=vs.85%29.aspx – Csaba Toth Aug 29 '13 at 15:21