使用四个不同端口的插槽处理连接

时间:2014-06-04 06:57:59

标签: c linux sockets select port

我尝试在Linux平台上使用C创建客户端/服务器系统。我想听四个不同的端口。因此,我创建了四个文件描述符,每个端口一个。此外,该进程将fd绑定到端口并开始监听它。这很好用。 此外,我使用select()来监听连接,在那里我遇到了问题。在第一次运行中,程序在select时等待,直到连接客户端。我用telnet发送一个字符串到服务器后继续。但是在循环的第二次运行中,程序在select处再次停止,并且只要新客户端连接就等待。即使我通过telnet发送一个新字符串,它也会在建立新连接后等待并处理。我使用的示例类似于this link。 因此我不使用超时。 为什么它会在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));
            }
        }
    }
}

1 个答案:

答案 0 :(得分:3)

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,你存储在client_address向量中。 您的代码有效地侦听新连接,接受它,读取数据,返回写入内容然后在不关闭它的情况下抛出套接字。