Использование select (..) на клиенте

Я пытаюсь реализовать select (..) на стороне клиента с созданием нескольких сокетов отдельно от TCP-сокета для recv (..) с сервера. Я хочу получать данные по различным recv (..) разных сокетов, созданных с помощью select (..). Кажется, что код функционирует должным образом. Пожалуйста помоги. Спасибо!

#include #include #include #include #include #include #include #include #include  int main(int argc, char *argv[]) { int count, createsocket, chunks, newsocket[5], i; int bufsize = 2048; char *buffer = malloc(bufsize); char fname[256]; struct sockaddr_in address; fd_set master; fd_set read_fds; int fdmax, j; FD_ZERO(&master); FD_ZERO(&read_fds); if((createsocket = socket(AF_INET, SOCK_STREAM, 0)) > 0) { printf("Socket created.\n"); } address.sin_family = AF_INET; address.sin_port = htons(15001); inet_pton(AF_INET, argv[1], &address.sin_addr); if(connect(createsocket, (struct sockaddr*)&address, sizeof(address)) == 0) { printf("Connected to server %s\n",argv[1]); } printf("Enter the file name to download\n"); scanf("%s",fname); send(createsocket, fname, sizeof(fname), 0); // printf("Enter the chunks of file to receive"); printf("waiting to receive the file from server..\n"); //code to create a new socket based on the number of chunks required for(i=0;i 0) { printf("new Socket %d created.\n", i); } } FD_SET(createsocket, &master); fdmax = createsocket; for(;;) { read_fds = master; if(select(fdmax+1, &read_fds, NULL, NULL, NULL) == -1){ perror("select"); exit(2); } for(i=0; i fdmax) { fdmax = newsocket[i]; } printf("still something is going on..\n"); } } else { printf("Doing something..\n"); for(j = 0; j  0) { perror("recv"); } else { write(1, buffer, count); } } } } } } } } // while((count = recv(createsocket, buffer, bufsize, 0)) > 0) // write(1, buffer, count); printf("EOF.\n"); for(i=0;i<4;i++) { close(newsocket[i]); } return close(createsocket); } 

    Два быстрых комментария:

    Во-первых, нам нужно будет установить файловый дескриптор (fd) – как много fds, как требует логика приложения – перед вызовом select () каждый раз в цикле while. Мы также должны установить fd_set в нули, прежде чем делать вышеуказанный шаг. Это происходит потому, что, когда select возвращает, он вернет тот же fd_set, но он установит только те, у которых установлено событие. Итак, один из способов сделать это – начать с чистого состояния, а затем установить все интересующие нас fds. Что-то вроде этого:

     FD_ZERO(&read_fd_set); FD_SET(createsocket, &master); // We should do this for all connections if(select(fdmax+1, &read_fds, NULL, NULL, NULL) == -1){ 

    Во-вторых, вы создаете все другие сокеты (помимо socketocket socket), вы открываете сокет TCP и ничего не делаете с ним. Если это клиент, по крайней мере, нам нужно будет вызвать connect (). Не настраивая явное соединение, мы не можем ничего использовать с сокетами TCP.

    Таким образом, комментарий высокого уровня состоит в том, что если вы хотите иметь N клиентских сокетов, затем откройте N сокетов и соедините все сокеты с сервером. Затем передайте все N fds в select () (каждый раз, когда вы вызываете select ()) и делаете это в цикле.

    Проблема в том, что вы вызываете recv() на сокеты, которые не готовы к чтению. Вот для чего подходит select() , чтобы рассказать вам, какие сокеты готовы к чтению. Ваша логика, вызывающая recv() обрабатывает всю коллекцию fds, а не только fds в готовом наборе.