在 c 中选择并发服务器 TCP

问题描述 投票:0回答:1

我有一个小问题,实际上我必须让两个客户端与我的并发服务器进行通信(执行不同的功能),

我发现我可以使用选择来解决这个问题,但是如果我尝试在代码中实现它,它会给我一个分段错误,有人可以帮助我吗?

我声明,以前与单个客户合作是一个寓言,现在不幸的是实现了选择,我破坏了一点“全部”,

我应该解决这个问题,你可以用 select() 做一个并发服务器吗? 你能告诉我这段代码哪里错了吗?

int main (int argc , char *argv[])
{
 int list_fd,conn_fd;
 int i,j;
 struct sockaddr_in serv_add,client;
 char buffer [1024];
 socklen_t len;
 time_t timeval;
 char fd_open[FD_SETSIZE];
 pid_t pid;
 int logging = 1;
 char swi;
 fd_set fset;
 int max_fd = 0;
 int waiting = 0;
 int compat = 0;

 sqlite3 *db;
 sqlite3_open("Prova.db", &db);

    start2();
    start3();

    printf("ServerREP Avviato \n");

    if ( ( list_fd = socket(AF_INET, SOCK_STREAM, 0) ) < 0 ) {
        perror("socket");
        exit(1);
    }

    if (setsockopt(list_fd, SOL_SOCKET, SO_REUSEADDR, &(int){ 1 }, sizeof(int)) < 0)
        perror("setsockopt(SO_REUSEADDR) failed");

  memset((void *)&serv_add, 0, sizeof(serv_add));   /* clear server address */
  serv_add.sin_family      = AF_INET;
  serv_add.sin_port        = htons(SERVERS_PORT2);
  serv_add.sin_addr.s_addr = inet_addr(SERVERS_IP2);


    if ( bind(list_fd, (struct sockaddr *) &serv_add, sizeof(serv_add)) < 0 ) {
       perror("bind");
        exit(1);
    }

    if ( listen(list_fd, 1024) < 0 ) {
        perror("listen");
        exit(1);
    }

    /* initialize all needed variables */
    memset(fd_open, 0, FD_SETSIZE);   /* clear array of open files */
    max_fd = list_fd;                 /* maximum now is listening socket */
    fd_open[max_fd] = 1;

    //max_fd = max(conn_fd, sockMED);
        while (1) { 
            FD_ZERO(&fset);
            FD_SET(conn_fd, &fset);
            FD_SET(sockMED, &fset);
            len = sizeof(client);

            if(select(max_fd + 1, &fset, NULL, NULL, NULL) < 0){exit(1);}

            if(FD_ISSET(conn_fd, &fset))
            { 
                if ( (conn_fd = accept(list_fd, (struct sockaddr *)&client, &len)) <0 )
                perror("accept error"); 
                exit(-1); 
            } 
         /* fork to handle connection */ 
            if ( (pid = fork()) < 0 ){      
                perror("fork error"); 
                exit(-1); 
            } 
            if (pid == 0) {                 /* child */ 
                close(list_fd);
                close(sockMED); 
                Menu_2(db,conn_fd);
                close(conn_fd); 
                exit(0); 
            } else {                        /* parent */ 
                close(conn_fd); 
        } 
        if(FD_ISSET(sockMED, &fset))
        MenuMED(db,sockMED);
        FD_CLR(conn_fd, &fset);
        FD_CLR(sockMED, &fset);
    } 

    sqlite3_close(db); 
    exit(0); 
} 
c server tcp posix-select
1个回答
1
投票

我不明白你在这里如何尝试使用

select
,以及为什么你想同时使用
fork
让孩子处理接受的连接套接字,以及
select

常见的设计有:

  • 多处理服务器:

    父进程设置监听套接字并循环等待与accept的实际连接。然后它分叉一个子进程来处理新接受的连接,并简单地等待下一个连接。

  • 多线程服务器:

    前一个的变体。主线程启动一个新线程来处理新接受的连接,而不是 fork 一个新进程。

  • 异步服务器:

    服务器设置一个

    fd_set
    来了解哪些套接字需要处理。最初,仅设置监听套接字。那么主循环是(伪代码:

    loop on select
      if the listening socket is present in read ready sockets, accept the pending connection and add is to the `fd_set`, then return to loop
      if another socket is present in read ready socket
        read from it
        if a zero read (closed by peer), close the socket and remove it from the `fd_set`
        else process the request and return to loop
    

    这里最困难的部分是处理需要很长时间,整个过程被阻塞,并且处理涉及发送大量数据,您也必须使用

    select
    来发送部分...

© www.soinside.com 2019 - 2024. All rights reserved.