Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/55.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 在四个不同端口使用套接字处理连接_C_Linux_Sockets_Select_Port - Fatal编程技术网

C 在四个不同端口使用套接字处理连接

C 在四个不同端口使用套接字处理连接,c,linux,sockets,select,port,C,Linux,Sockets,Select,Port,我尝试在Linux平台上用C语言制作一个客户机/服务器系统。我想在四个不同的端口上收听。因此,我创建了四个文件描述符,每个端口一个。此外,进程将fd绑定到端口并开始侦听它。这个很好用。 此外,我还使用select()来侦听连接,在那里我遇到了一个问题。在第一次运行中,程序在select上等待,直到连接了客户端。在我用telnet向服务器发送一个字符串后,它将继续。但在循环的第二次运行中,程序再次在select停止,并等待新客户机连接。即使我通过telnet发送新字符串,它也会在建立新连接后等待并

我尝试在Linux平台上用C语言制作一个客户机/服务器系统。我想在四个不同的端口上收听。因此,我创建了四个文件描述符,每个端口一个。此外,进程将fd绑定到端口并开始侦听它。这个很好用。 此外,我还使用
select()
来侦听连接,在那里我遇到了一个问题。在第一次运行中,程序在select上等待,直到连接了客户端。在我用telnet向服务器发送一个字符串后,它将继续。但在循环的第二次运行中,程序再次在select停止,并等待新客户机连接。即使我通过telnet发送新字符串,它也会在建立新连接后等待并处理。我使用的示例类似于。 因此,我不使用超时。 为什么它要在select上等待新连接?我如何处理这个问题

我的代码:

FD_ZERO(&read_sock);
FD_SET(fd[0], &read_sock);
FD_SET(fd[1], &read_sock);
FD_SET(fd[2], &read_sock);
FD_SET(fd[3], &read_sock);
while(TRUE){
    fprintf(stderr,"Waiting for incoming connections...\n");
    status = select(maxfd+1,&read_sock,NULL,NULL,NULL);
    fprintf(stderr,"Number of fd: %d\n",status);
    if(status>0){
        for(int i=0; i< FD_SET_SIZE; i++){
            if(FD_ISSET(fd[i], &read_sock)){
                fd_accept=accept(fd[i],(struct sockaddr*)&client_address[i], &len);
                 if(client_sock[i] < 0) {
                     client_sock[i] = fd_accept;
                }
                int lenght = recv(client_sock[i],data,BUFFER-1,0);
                if(lenght>0){
                    data[lenght] = '\0';
                    fprintf (stderr,"Received: %s\n", data);
                }else if(lenght==0){
                    getpeername(fd[i],(struct sockaddr*)&client_address[i], &len);
                    close(fd[i]);
                    client_sock[i] = -1;
                }else{
                    fprintf(stderr,"Error: %d\n",errno);
                }

                char string[] = "Test"; //sends a char Test to the client

                write(client_sock[i],&string,sizeof(string));
            }
        }
    }
}
FD_ZERO(&read_sock);
FD_集(FD[0],&read_sock);
FD_集(FD[1],&read_sock);
FD_集(FD[2],&read_sock);
FD_集(FD[3],&read_sock);
while(TRUE){
fprintf(stderr,“等待传入连接…\n”);
状态=选择(maxfd+1,&read\u sock,NULL,NULL);
fprintf(标准,“fd数量:%d\n”,状态);
如果(状态>0){
对于(int i=0;i0){
数据[长度]='\0';
fprintf(标准格式,“接收到:%s\n”,数据);
}else如果(长度==0){
getpeername(fd[i],(struct sockaddr*)和客户端地址[i],&len);
关闭(fd[i]);
客户端_sock[i]=-1;
}否则{
fprintf(标准,“错误:%d\n”,错误号);
}
char string[]=“Test”;//向客户端发送一个char测试
写入(client_sock[i],&string,sizeof(string));
}
}
}
}

选择
是一种阻塞操作。从手册页:

select() and pselect() allow a program to monitor multiple file descriptors, 
waiting until one or more of the file descriptors become "ready" for some class
of I/O operation (e.g., input possible). A file descriptor is considered ready
if it is possible to perform the corresponding I/O operation (e.g., read(2))
without blocking.
因为您给它的描述符是侦听器套接字,所以它将阻塞,直到其中一个上有新的套接字为止

如果要侦听其中一个已接受套接字上的数据,还需要
在套接字描述符上选择
,该描述符存储在
客户端地址
向量中。
您的代码有效地侦听新的连接,接受它,读取数据,写一些东西作为回报,然后在不关闭套接字的情况下将其丢弃。

select
是一种阻塞操作。从手册页:

select() and pselect() allow a program to monitor multiple file descriptors, 
waiting until one or more of the file descriptors become "ready" for some class
of I/O operation (e.g., input possible). A file descriptor is considered ready
if it is possible to perform the corresponding I/O operation (e.g., read(2))
without blocking.
因为您给它的描述符是侦听器套接字,所以它将阻塞,直到其中一个上有新的套接字为止

如果要侦听其中一个已接受套接字上的数据,还需要
在套接字描述符上选择
,该描述符存储在
客户端地址
向量中。
您的代码有效地侦听新的连接,接受它,读取数据,写一些东西作为回报,然后在不关闭套接字的情况下将其丢弃。

select
是一种阻塞操作。从手册页:

select() and pselect() allow a program to monitor multiple file descriptors, 
waiting until one or more of the file descriptors become "ready" for some class
of I/O operation (e.g., input possible). A file descriptor is considered ready
if it is possible to perform the corresponding I/O operation (e.g., read(2))
without blocking.
因为您给它的描述符是侦听器套接字,所以它将阻塞,直到其中一个上有新的套接字为止

如果要侦听其中一个已接受套接字上的数据,还需要
在套接字描述符上选择
,该描述符存储在
客户端地址
向量中。
您的代码有效地侦听新的连接,接受它,读取数据,写一些东西作为回报,然后在不关闭套接字的情况下将其丢弃。

select
是一种阻塞操作。从手册页:

select() and pselect() allow a program to monitor multiple file descriptors, 
waiting until one or more of the file descriptors become "ready" for some class
of I/O operation (e.g., input possible). A file descriptor is considered ready
if it is possible to perform the corresponding I/O operation (e.g., read(2))
without blocking.
因为您给它的描述符是侦听器套接字,所以它将阻塞,直到其中一个上有新的套接字为止

如果要侦听其中一个已接受套接字上的数据,还需要
在套接字描述符上选择
,该描述符存储在
客户端地址
向量中。
您的代码有效地侦听新的连接,接受它,读取数据,写入一些东西作为回报,然后在不关闭套接字的情况下将其丢弃。

就是这样!OP中的程序只等待新的连接。它可以按预期工作:-)如果我理解正确,我必须将第一次运行到第二次运行的fdmax更改为新的fdmax值。fdmax可能不需要更改-取决于描述符值。但可能是的。但是,你也必须使用<代码> FDYSETA/COD>新的描述符,或者SCONE不考虑它,就是这样!OP中的程序只等待新的连接。它可以按预期工作:-)如果我理解正确,我必须将第一次运行到第二次运行的fdmax更改为新的fdmax值。fdmax可能不需要更改-取决于描述符值。但可能是的。但是,你也必须使用<代码> FDYSETA/COD>新的描述符,或者SCONE不考虑它,就是这样!OP中的程序只等待新的连接。它可以按预期工作:-)如果我理解正确,我必须将第一次运行到第二次运行的fdmax更改为新的fdmax值。fdmax可能不需要更改-取决于描述符值。但可能是的。但是,你也必须使用<代码> FDYSETA/COD>新的描述符,或者SCONE不考虑它,就是这样!OP中的程序只等待新的连接。它可以按预期工作:-)如果我理解正确,我必须将第一次运行到第二次运行的fdmax更改为新的fdmax值。fdmax可能不需要更改-取决于描述符值。但可能是的。但是您也必须“代码> FDySET//COD>新的描述符,或者SELECT不会考虑它。