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

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

我尝试在Linux平台上用C语言制作一个客户端/服务器系统。我想监听四个不同的端口。因此,我创建了四个文件描述符,每个端口一个。此外,该进程将 fd 绑定到端口并开始侦听它。这很好用。 此外,我使用

select()
来监听连接,但遇到了问题。在第一次运行时,程序在 select 处等待,直到客户端连接。当我用 telnet 发送一个字符串到服务器后,它会继续。但在循环的第二次运行中,程序再次在 select 处停止,并等待新客户端连接。即使我通过 telnet 发送新字符串,它也会在建立新连接后等待并处理该字符串。我使用的示例类似于此链接。 因此我不使用超时。 为什么它在选择时等待新连接?我该如何处理这个问题?

我的代码:

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));
            }
        }
    }
}
c linux sockets port posix-select
1个回答
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
向量中。 您的代码有效地侦听新连接,接受它,读取数据,写入一些内容作为返回,然后丢弃套接字而不关闭它。

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