Необычное поведение select / sock stream поведение

Я пишу небольшую программу для запроса фрагмента файла, а затем другая программа возвращает этот конкретный фрагмент файла. Я могу заставить это работать, используя файлы размером до 555000 байт, но на чем-то большем, я получаю необычное поведение.

В моем цикле я проверяю буфер прогресса, который является массивом целых чисел, чтобы увидеть, есть ли у меня определенный фрагмент файла. Если я это сделаю, то я не отправляю запрос на этот чанк, но если я не делаю, то я запрашиваю чанк от сверстника. У меня есть связанный список, по которому я перемещаюсь, где с каждым пэром в списке связан sockfd. Так что, в некотором смысле, я "разбираю" запросы. После того, как я отправляю их, я жду поступления сообщений. Я не знаю, является ли это лучшим подходом, но он казался наиболее естественным.

Однако для файлов большего размера он зависает при вызове select. Я не совсем уверен, почему. Если кто-то может пролить свет на это или предложить лучший подход, я хотел бы услышать это.

Вот мой код Я не включил код для функций, которые я вызываю, но я не думаю, что это необходимо в этом случае (они являются модифицированными версиями функций sendall и recvall Beej). Также стоит упомянуть, что это в многопоточном приложении (с использованием pthreads), но я не использую какие-либо общие переменные. Спасибо, что нашли время, чтобы прочитать это!

total = (number of chunks in the file)
my_peers = (linked list of peer structs containing sockfds, etc)
int i;
progress_buf = (array of ints, each representing a chunk in a file, 0 means we don't have the chunk)

while (1) {

    /* Send out the chunk requests */
    for(z= 0; z < total; z++) {

        /* Circles through the peer list */
        if (temp -> next != NULL) {
            temp_next = temp->next;
        } else {
            temp_next = my_peers;
        }

        if (progress_buf[z] == 0) { 
            /* Request_blocks performs a send */ 

            /* Need to deal with the "hanging bytes" chunk */       
            if (((z + 1) == total) && (remainder_chunk == 1)) {           
                check = request_blocks(temp, remainder, remainder_chunk, z);
            } else {
                check = request_blocks(temp, remainder, 0, z);
            }

            /* Bad send, remove peer from file descriptors and list */
            if (check != 0 ) {          
                FD_CLR(check, &masterr);
                remove_peer(&my_peers, temp->socket);
            }
        }     
        temp = temp_next;
    }

    read_fdss = masterr; 

    /* HANGS RIGHT HERE */
    if (select(fdmax+1, &read_fdss, NULL, NULL, NULL) < 0) {
        perror("select"); 
    }

    read_fdss = masterr;

    int got_block;
    /* Means we've received a block */
    for(i = 4; i <= fdmax; i++) {
        got_block = -1;
        if (FD_ISSET(i, &read_fdss)) {

            /* Performs a recv */
            got_block = receive_block(i, filename_copy, progress_buf);

            /* Update the progress buffer */
            if (got_block > -1)  {
                remaining_blocks++;
                if (remaining_blocks == total) goto finished;
                    /* Failure- remove the peer */  
                } else if (got_block == -2) {
                    close(i);
                    FD_CLR(i, &masterr);
                    remove_peer(&my_peers, i);
                }
            }
        }
    }
}

0 ответов

Другие вопросы по тегам