gpt4 book ai didi

c 中带有 select 的并发服务器 TCP

转载 作者:行者123 更新时间:2023-11-30 14:51:02 25 4
gpt4 key购买 nike

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

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

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

我应该解决这个问题,你可以用 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);
}

最佳答案

我无法理解您如何尝试在此处使用select,以及为什么要使用fork让子进程处理接受的连接套接字,以及 >选择

常见的设计有:

  • 多处理服务器:

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

  • 多线程服务器:

    前一个的变体。主线程启动一个新线程来处理新接受的连接,而不是 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 来发送部分...

关于c 中带有 select 的并发服务器 TCP,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48610207/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com