Thread: Server with multiple clients

  1. #1
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681

    Server with multiple clients

    Finally got my server and client programs talking WOOHOO. Now on to the next part:

    I want multiple clients to be able to connect and stay connected to a singlar server. What I was thinking of having the client connect to a predefined port, then having the server respond with another port number, having the client disconnect, and then reconnect to the new port.

    I'm using WSAAsyncSelect, where is the socket info passed in the window message? Or would I need to setup a different message for each port?

    I don't really need a lot of help with the actual coding, just need help with the design.

    Thanks.

  2. #2
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Sounds complicated.

    ...why not use the tried and true? The basic steps are:

    1) bind() a single socket to a port.
    2) listen().
    3) launch a thread to accept() a client.
    4) repeat step 3

    Since listen limits itself to something like 5, you will have to call it again after the limit is reached. Anyway, I'm not knocking you're idea, just not such a good thing to push the envelope in the R&D phase, if you know what I mean.
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  3. #3
    Banned nickname_changed's Avatar
    Join Date
    Feb 2003
    Location
    Australia
    Posts
    986
    Thantos you've got it all wrong, you don't need to have a seperate port for each client. Test it yourself, have your client on 2 seperate networked computers and connect to the server at exactly the same time, you'll see you should get responses back at the same time too (it would be exact, but then you'd have to use multithreading and other crap). You don't need a seperate port for each client that connects to a server.

  4. #4
    C++ Developer XSquared's Avatar
    Join Date
    Jun 2002
    Location
    Ontario, Canada
    Posts
    2,718
    As long as each client has its own socket, you don't need to worry about ports.
    Naturally I didn't feel inspired enough to read all the links for you, since I already slaved away for long hours under a blistering sun pressing the search button after typing four whole words! - Quzah

    You. Fetch me my copy of the Wall Street Journal. You two, fight to the death - Stewie

  5. #5
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    Damn after I worked all day to almost get my idea done

    I asked for the sole reason of finding better solutions

    Thanks for the suggestions. I got all the coding done up to accept() and then the lightblub hit me and I realize I was making a mistake.

    Another question, is it possible to use the SAME socket when processing accept()?

    Reason I'm asking is that I want my admin ports on seperate ports and window messages then my client.

    Thanks for all the help though, I'm getting a much better of socket programming each time I rewrite the server program

    Edit: One more thing: The max number of connections for listen is 5, however the help file I have says that
    backlog [in] The maximum length to which the queue of pending connections can GROW. If this value is SOMAXCONN, then the underlying service provider responsible for socket s will set the backlog to a maximum “reasonable” value.
    Am I correct that by proccessing the connection request, and accept() the number would decrease. IE if I have 3 pending connections, proccess accept() then the number would decrease to 2?
    Last edited by Thantos; 08-30-2003 at 11:16 PM.

  6. #6
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    >> ...IE if I have 3 pending connections...

    Correct.

    >> is it possible to use the SAME socket when processing accept()?

    I'm not sure I follow you. The first arg to accept() is the listening socket which, yes, is constantly reused. The return value of
    accept() is the actual connection socket to the client, which doesn't get reused (well, at least not until you're done with it, and close it, etc).

    >> I'm getting a much better of socket programming each time I rewrite the server program

    That's actually my credo in a nutshell: Write it, run it, delete it, write it, run it, delete it, ad infinitum. It's great practice!
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  7. #7
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    Ok I see what you are saying. One socket is JUST for listening. Was hoping I could reassign it as a quasi security mesasure Basically I want my admin ports to allow only one connection at a time.

    Ah well I'll figure something else out

  8. #8
    Banned nickname_changed's Avatar
    Join Date
    Feb 2003
    Location
    Australia
    Posts
    986
    Ok, this comes straight from my web server:

    Code:
    while (!SERVER_STOP)
    {
    	SFD_New = accept(SFD_Listen, (struct sockaddr *) &ClientAddress, &Size);
    		
    	DWORD dwThreadId;
    	HANDLE hThread; 
    
    	// Create a structure of type ARGUMENT to be passed to the new thread
    	ARGUMENT Argument;
    	Argument.CLA = ClientAddress;
    	Argument.SFD = SFD_New;
    
    	// CreateThread and process the request
    	hThread = CreateThread( 
            NULL,					// default security attributes 
            0,                           		// use default stack size  
            ProcessRequest,                 	// thread function 
            &Argument,                		// argument to thread function 
            0,                           		// use default creation flags 
            &dwThreadId);                		// returns the thread identifier 
    		
    	if (hThread != NULL)	
    	{
    		CloseHandle( hThread );
    	}
    
    }
    This is how it works: Accept waits for a connection from a client. When it gets a connection, it puts the socket for the client in SFD_New. Then it creates a new thread to handle the connection, and gets back to accept()ing. This can handle multiple clients because a new thread is created each time, allowing the server to get back to listening.

    If I was to take out the new thread creation, so It looked like this:
    Code:
    while (!SERVER_STOP)
    {
    	SFD_New = accept(SFD_Listen, (struct sockaddr *) &ClientAddress, &Size);
    		
    	// Do some stuff with SFD_New.
    
    	closesocket(SFD_New);
    }
    It would not accept a new client UNTIL the first one had finished processing. Get it now? So, if your Admin ports were like the second example, they could only have one connection at a time. But if they were like the first, they could have multiple
    Last edited by nickname_changed; 08-31-2003 at 07:56 PM.

  9. #9
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    From your code segment it appears that you are using a blocking server. I can't allow that in a window's eviroment. I've figured out what I need/want to do.

  10. #10
    C++ Developer XSquared's Avatar
    Join Date
    Jun 2002
    Location
    Ontario, Canada
    Posts
    2,718
    If you want it to be non-blocking, just throw the accept( ) loop itself into a separate thread from your WndProc.
    Naturally I didn't feel inspired enough to read all the links for you, since I already slaved away for long hours under a blistering sun pressing the search button after typing four whole words! - Quzah

    You. Fetch me my copy of the Wall Street Journal. You two, fight to the death - Stewie

  11. #11
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    I'll post my code when I'm done with it. I think I got a pretty good set of code going, without using threads.

  12. #12
    Banned nickname_changed's Avatar
    Join Date
    Feb 2003
    Location
    Australia
    Posts
    986
    Both segments were blocking sockets, but for the first one it doesn't matter. To use non-blocking, search for select() in Beej's. That will show you how to create a non-blocking server.

  13. #13
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    Don't need select() for a non-blocking server

  14. #14
    Banned nickname_changed's Avatar
    Join Date
    Feb 2003
    Location
    Australia
    Posts
    986
    Well unless your using threads or some sort of winsock2 WSA function, select() is the only normal way to create a non-blocking socket.

  15. #15
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    Socket 2 function but works really well: WSAAsyncSelect

    In DevC++ I was able to use it without including winsock2.h however.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Multiple clients to "internet" server
    By Zarniwoop in forum C Programming
    Replies: 2
    Last Post: 10-11-2008, 11:04 PM
  2. TCP Sockets: multiple clients - one server
    By Printisor in forum C Programming
    Replies: 4
    Last Post: 11-01-2007, 10:34 AM
  3. MISO Soup: Multiple Clients and one Server
    By doubleanti in forum Networking/Device Communication
    Replies: 2
    Last Post: 07-24-2007, 02:29 AM
  4. Socket Help - Multiple Clients
    By project95talon in forum C Programming
    Replies: 5
    Last Post: 11-17-2005, 02:51 AM
  5. server with multiple clients
    By Unregistered in forum C Programming
    Replies: 1
    Last Post: 02-23-2002, 09:15 PM