如何使用套接字连续接受来自不同客户端的多条消息?

时间:2013-08-06 06:34:47

标签: c++ linux sockets

首先我用c ++编写代码并在Linux / CentOS 6.4中运行

所以经过很长一段时间并在套接字上阅读了很多不同的书籍后,我终于至少让我的客户端和我的服务器部分工作了。

首先,我想继续接受来自不同客户端的消息,我已经设置了客户端,并且最终成功编译了它。现在我需要设置我的服务器,以便我可以正确测试。

我正在做的是用套接字实现餐饮哲学家问题,每个客户/哲学家代表不同的过程。我将要完成整个过程,服务器将跟踪所有内容,例如所有客户端的状态。这太难了,我现在刚创建客户端只是为了将他们的状态发送到服务器而服务器将其打印出来。

我正在考虑将do / while循环连续接受消息,但不确定应该使用什么来停止循环。请注意,我将在我的客户端设置一个while循环,并在经过一段时间后发出信号停止。然后它应该关闭该特定客户端。我的服务中有一个信号,但我不确定它是否有效。

#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);

    }
}

2 个答案:

答案 0 :(得分:1)

您需要一个多路复用系统调用,如poll(2)(或旧的,几乎过时的,select(2)系统调用)。您可能想要使用一些(或实现自己的)事件循环。见this&amp; that回答。阅读C10K problem

每个服务器都需要一个事件循环。

阅读Advanced Linux Programming(或一些Posix网络编程手册)。

答案 1 :(得分:0)

您可能只想在tcpserver下运行服务器程序(请参阅http://cr.yp.to/ucspi-tcp.html)。每次客户端连接到您的程序时(在您指定的端口上),这将生成程序的新实例。这样,你可以专注于你的程序的核心逻辑,并让tcpserver处理所有繁重的程序,如套接字编程等.tcpserver将输入从客户端传递到程序的stdin,并从程序stdout输出将被送回客户端。