Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/71.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 选择不扫描2个以上描述符的系统调用_C_Linux_Sockets - Fatal编程技术网

C 选择不扫描2个以上描述符的系统调用

C 选择不扫描2个以上描述符的系统调用,c,linux,sockets,C,Linux,Sockets,我正在编写一个服务于多个clientmax 5的服务器程序。当任何客户端连接到服务器时,服务器将描述符存储到一个数组中,并通过Select系统调用检查这些描述符中的任何活动。但是,它只从任意两个客户端读取数据,并且根本不提供rest客户端请求。下面是服务器的代码 #define NUM_CLIENT 5 void main(int argc,char** argv) { int master_sock, newSocket, err; struct sockaddr_in Server_a

我正在编写一个服务于多个clientmax 5的服务器程序。当任何客户端连接到服务器时,服务器将描述符存储到一个数组中,并通过Select系统调用检查这些描述符中的任何活动。但是,它只从任意两个客户端读取数据,并且根本不提供rest客户端请求。下面是服务器的代码

#define NUM_CLIENT 5

void main(int argc,char** argv)
{
 int master_sock, newSocket, err;
 struct sockaddr_in Server_addr, Client_addr;
 char buf[100]; 
 int i=0;
 int activity;

 //socket descriptors for select
 fd_set readfd;
 int client_fd[NUM_CLIENT]={-1,-1,-1,-1,-1};    

 //Socket creation
 master_sock= socket(AF_INET,SOCK_STREAM,0);
 if(master_sock<0){
    perror("socket");
    return;
 }

 //structure filling for listening to the port
 Server_addr.sin_family = AF_INET;
 Server_addr.sin_port = htons(atoi(argv[1]));
 Server_addr.sin_addr.s_addr = INADDR_ANY;

 //Binding to the Address and port filled in structure
 err = bind(master_sock,(struct sockaddr*)&Server_addr,sizeof(Server_addr));
 if(err<0){
    perror("socket");
    return;
 }

 printf("\nlistening to port");
 err = listen(master_sock,NUM_CLIENT);  //to inform, the willlingness to accept connections.
 if(err<0){
    perror("Listen");
    return;
 }
 printf("\nAccepting connection");

 while(1)
 {
    //Select modifies the objects in structure for any activity,
    // So we need to load them again.
    FD_ZERO(&readfd);   //clearing the readfd list
    FD_SET(master_sock,&readfd);    //adding the descriptor for select to listen

    for(i=0;i<NUM_CLIENT;i++){      
        if(client_fd[i] != -1){
            FD_SET(client_fd[i],&readfd);   //Add socket to the list

        }           
    }
    //Descriptors loaded..

    //start Select operation....

    activity = select(NUM_CLIENT+1,&readfd,NULL,NULL,NULL); //wait here until any activiy occurs
    if(activity < 0){
        perror("Select");break;
    }
    printf("\nactivity happened in socket...");

    //If activity related to master socket i.e. New client is trying to connect.
    if( FD_ISSET(master_sock,&readfd) ) {
        printf("\nactivity in master socket...");
        int len = sizeof(Client_addr);

        //Accept the connection
        newSocket = accept(master_sock, (struct sockaddr*)&Client_addr ,&len);  //blocking call
        if(newSocket<0){
            perror("accept");return;
        }
        printf("\nNew connection accepted");    

 //     puts("Receiving data");
        if( recv(newSocket,buf,100,0) > 0 )     //blocking call
            printf("\n%s",buf);
        else
            strcpy(buf,"hey");

//      puts("Sending data");   
        if( send(newSocket,buf,strlen(buf),0) < 0 )
            perror("send");


        //creating client database of descriptors
        for(i=0;i<NUM_CLIENT;i++){
            printf("\nfd[%d] = %d\n",i,client_fd[i]);           
            if(client_fd[i] == -1){
                client_fd[i]= newSocket;
                //FD_SET(newSocket,&readfd);    //Add socket to the list
                //printf("\nfd[%d] = %d\n",i,client_fd[i]);         
                break;
            }

        }

    }

    //If activity(read or write) in other sockets, check it out
    printf("\nChecking Activity in Other File Descriptors\n");
    for(i=0;i<NUM_CLIENT;i++){

        if(FD_ISSET(client_fd[i],&readfd)){

            printf("\nactivity in client %d ...",i);
 //     puts("Receiving data");
            if( recv(client_fd[i],buf,100,0) > 0 )  //blocking call
                puts(buf);  
            else
                strcpy(buf,"hello");
 //     puts("Sending data");   
            if( send(client_fd[i],buf,strlen(buf)+1,0) == -1 )
                perror("send");
                //printf("\n%s",buf);
        }

    }



  }



 }
每个客户机在通过命令行提供的给定时间睡眠后发送和接收数据。示例:客户端1 5秒、客户端2 4秒等等

客户端的代码为:

void main(int argc, char** argv)
{
 int fd, err;
 char buf[100],buf2[100];
 struct sockaddr_in server;

 fd = socket(AF_INET,SOCK_STREAM,0);
 if(fd<0){
    perror("socket");return;
 }

I2A(buf,getpid());  //Integer to array conversion, returns array
strcat(buf,"Hello");

printf("%s\n",buf);
server.sin_family = AF_INET;
server.sin_port = htons(atoi(argv[1])); //Host to network
server.sin_addr.s_addr = inet_addr("127.0.0.1");
printf("Connecting with server\n");
if( connect(fd, (struct sockaddr*)&server,sizeof(server) ) < 0) {
    perror("connect");return;
}
printf("Connected with server\n");

while(1){

//  printf("Sending data\n");
 if( send(fd,buf,20,0) < 0)
    perror("send");

 // printf("Receiving data\n"); 
 if( recv(fd,buf2,sizeof(buf2),0) >0 )
    printf("%s\n",buf2);
 sleep(atoi(argv[2]));  
 }
提前谢谢。

这行是错的:

activity = select(NUM_CLIENT+1,&readfd,NULL,NULL,NULL); //wait here until any activiy occurs
要选择的第一个参数不应是NUM_CLIENT+1,而应是您调用FD_SET on的所有文件描述符值的最大文件描述符值加上一个。

此行错误:

activity = select(NUM_CLIENT+1,&readfd,NULL,NULL,NULL); //wait here until any activiy occurs

要选择的第一个参数不应是NUM_CLIENT+1,而应是您调用FD_SET on的所有文件描述符值的最大文件描述符值,再加上一个。

NUM_CLIENT的名称不正确。要听的第二个参数是backlog队列的长度,而不是客户端的数量,它与select的第一个参数无关。请指定backlog队列的重要性好吗?为什么不能像这里这样使用NUM_客户机?文档中已经指定了“backlog队列的重要性”,我已经解释了称它为NUM_客户机的错误。我不知道你为什么要我重复一遍。NUM_客户的名字不好。要听的第二个参数是backlog队列的长度,而不是客户端的数量,它与select的第一个参数无关。请指定backlog队列的重要性好吗?为什么不能像这里这样使用NUM_客户机?文档中已经指定了“backlog队列的重要性”,我已经解释了称它为NUM_客户机的错误。我不知道你为什么要我重复一遍。