Search code examples
client-serversendsocks

Client to server connection only sending not receiving


This is my case, I have a server listening for connections, and a client that I'm programming now. The client has nothing to receive from the server, yet it has to be sending status updates every 3 minutes.

I have the following at the moment:

    WSAStartup(0x101,&ws);
    sock = socket(AF_INET,SOCK_STREAM,0);
    sa.sin_family = AF_INET;
    sa.sin_port = htons(PORT_NET);
    sa.sin_addr.s_addr = inet_addr("127.0.0.1"); 
    connect(sock,(SOCKADDR*)&sa,sizeof(sa));
    send(sock,(const char*)buffer,128,NULL);

How should my approach be? Can I avoid looping recv?


Solution

  • That's rather dependant on what behaviour you want and your program structure. By default a socket will block on any read or write operations, which means that if your try and have your server's main thread poll the connection, you're going to end up with it 'freezing' for 3 minutes or until the client closes the connection.

    The absolute simplest functional solution (no multithreadding) is to set the socket to non-blocking, and poll in in the main thread. It sounds like you want to avoid doing that though.

    The most obvious way around that is to make a dedicated thread for every connection, plus the main listener socket. Your server listens for incoming connections and spawns a thread for each stream socket it creates. Then each connection thread blocks on it's socket until it receives data, and either handles it itself or shunts it onto a shared queue. That's a bulky and complex solution - multiple threads which need opening and closing, shared resources which need protecting.

    Another option is to set the socket to non-blocking (Under win32 use setsockopt so set a timeout, under *nix pass it the O_NONBLOCK flag). That way it will return control if there's no data available to read. However that means you need to poll the socket at reasonable intervals ("reasonable" being entirely up to you, and how quickly you need the server to act on new data.)

    Personally, for the lightweight use you're describing I'd use a combination of the above: A single dedicated thread which polls a socket (or an array of nonblocking sockets) every few seconds, sleeping in between, and simply pushed the data onto a queue for the main thread to act upon during it's main loop.

    There are a lot of ways to get into a mess with asynchronous programs, so it's probably best to keep it simple and get it working, until you're comfortable with the control flow.