简体   繁体   中英

How to continuously accept multiple messages from different clients using sockets?

Firstly I'm coding in c++ and running in Linux/CentOS 6.4

So after a really long time and reading a lot of different books on sockets, I finally have at least my client and my server partially working.

First I want to continuously accept messages from different clients, I have already setup the client, and it finally successfully compiled at least. Now I need to set up my server so that I can properly test.

What I'm doing is implementing the dining philosopher problem with sockets, with each client/philosopher representing a different process. I was going to go through this whole thing, where the server was going to keep track of everything, like the states of all the client. That was too difficult, I have now just created the client just to send their status to the server and the server prints it out.

I was thinking of putting a do/while loop to continuously accept messages, but not sure what I should use to stop the loop. Note that I will have a while loop set up in my client, which is signaled to stop after an elapsed amount of time. It should then close that particular client. I do have a signal in my serve, but I am not sure it works.

#include "helper.h"
  char buffer[4096];
void sigchld_handler(int signo)
{
  while (waitpid(-1, NULL, WNOHANG) > 0);
}
void client(int &newsock, int nread)
{
do
            {

                int nread = recv(newsock, buffer,sizeof(buffer), 0);
                     puts(buffer);


            }while(nread!=0);
} 


int main(int argc, char *argv[])
{
    struct sockaddr_in sAddr, cli_addr;
    socklen_t client_len;
    int listensock;
    int newsock;

    int result;
    int nread=1;
     pid_t childid; ;
    int status;

    if((listensock = socket(AF_INET, SOCK_STREAM, 0))<0)
    {
        perror("Problem in creating socket");
        exit(2);
    }


    sAddr.sin_family = AF_INET;
    sAddr.sin_port = htons(3333);
    sAddr.sin_addr.s_addr = htonl(INADDR_ANY);

  bind(listensock, (struct sockaddr *) &sAddr, sizeof(sAddr));
    if (result < 0) {
        perror("exserver2");
        return 0;
    }

    result = listen(listensock, 5);
    if (result < 0) {
        perror("exserver2");
        return 0;
    }

    signal(SIGCHLD, sigchld_handler);

    while (1) {
    client_len = sizeof(cli_addr);
        newsock = accept(listensock,(struct sockaddr *)&cli_addr, &client_len);
        if ((childid = fork()) == 0) {
            printf("child process %i created.\n", getpid());
            close(listensock);
            client(newsock, nread);


            }
            if(status<0)
            {
            printf("%s\n" "Read error");
            exit(1);
            }

            close(newsock);

    }
}

You need a multiplexing syscall like poll(2) (or the old, nearly obsolete, select(2) syscall). You may want to use some (or implement your own) event loop. See this & that answer. Read about the C10K problem .

Every server needs an event loop.

Read Advanced Linux Programming (or some Posix network programming book).

You may want to simply run your server program under tcpserver (see http://cr.yp.to/ucspi-tcp.html ). This will spawn a new instance of your program each time a client connects to your program (on the port that you specify). This way, you can focus on the core logic of your program, and let tcpserver handle all of the heavy lifting as far as the socket programming, etc. tcpserver will pass input from the client to your program's stdin, and output from your programs stdout will be sent back to the client.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM