不寻常的选择/袜子流行为行为

我正在编写一个小程序来请求一个文件块,然后让另一个程序返回该文件的特定块。 我可以使用最多大约555000字节的文件来使用它,但是在比这更大的任何事情上,我得到了不寻常的行为。

在我的循环中,我检查进度缓冲区,它是一个整数数组,以查看我是否有一个特定的文件块。 如果我这样做,那么我不会发送对该块的请求,但如果我没有,那么我从对等方请求块。 我有一个链接列表,我移动了,列表中的每个对等方都有一个与之关联的sockfd。 所以,从某种意义上说,我“循环”了这些要求。 一旦我把它们发出去,我就会等待消息进来。我不知道这是否是最好的方法,但它似乎是最自然的。

但是,对于较大的文件,它会在select调用时挂起。 我不完全确定为什么。 如果有人能够对此有所了解,或建议采取更好的方法,我很乐意听到。

这是我的代码。 我没有包含我调用的函数的代码,但我认为在这种情况下它不是必需的(它们是Beej的sendall和recvall函数的修改版本)。 还值得一提的是,这是一个multithreading应用程序(使用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  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  -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); } } } } }