Выберите системный вызов, не сканирующий более 2 дескрипторов

Я пишу серверную программу, обслуживающую несколько клиентов (максимум 5). Когда любой клиент подключается к серверу, сервер сохраняет дескриптор в массиве и проверяет любую активность в этих дескрипторах с помощью системного вызова Select. Но это только чтение от любых двух клиентов, а запросы остальных клиентов не обслуживаются вообще. Вот код для сервера

#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);
        }

    }



  }



 }

И каждый клиент отправляет и получает данные после сна в течение определенного времени (предоставляется через командную строку). Пример: client1 5sec, client2 4sec и так далее ...

Код для клиента:

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]));  
 }

Заранее спасибо.

# sockets
Источник
  • 0
    NUM_CLIENT плохо назван. Второй аргумент listen() - это длина очереди невыполненных работ, а не количество клиентов, и он не имеет никакого отношения к первому аргументу select() .
  • 0
    Не могли бы вы указать значение очереди невыполненных работ? Почему это не может быть NUM_client, как здесь?
  • 0
    «Значение очереди невыполненных работ» уже указано в документации, и я уже объяснил, что не так, называя ее NUM_CLIENT . Я не знаю, почему вы просите меня повторяться.
Codelisting
Codelisting
Популярные категории
На заметку программисту