我有一个由 6 个套接字组成的数组,每个套接字都旨在侦听传入的消息。在每个套接字上,我需要调用 select() 来监听传入的消息。这段代码可以编译,但是当我运行它时,我会收到一条消息
select failure: Invalid argument
errno: 22
谁能看到我做错了什么?谢谢!
这段代码在 int main() 中:
int listenfd[6];
fd_set read_set;
struct timeval tv;
time_t start_time;
make_connections(listenfd, neighbor, servAddr, read_set);
FD_ZERO(&read_set);
// add the accepted connections to the read set for use with select()
for (i=0; i<6; i++) {
FD_SET(listenfd[i], &read_set);
}
tv.tv_sec = 5; // seconds
tv.tv_usec = 5000000; // microseconds
gettimeofday(&tv, NULL);
start_time = tv.tv_sec;
// EDIT: made the following change per suggestion by ThePelaton
// same error exists, though
//if ( (select(6, &read_set, NULL, NULL, &tv)) == -1) {
int max = listenfd[0];
for (i=1; i<6; i++) {
if (listenfd[i] > listenfd[i-1]) {
max = i;
}
}
if ( (select(listenfd[max]+1, &read_set, NULL, NULL, &tv)) == -1) {
perror("select failure");
fprintf(stdout, "errno: %d\n", errno);
exit(EXIT_FAILURE);
}
我的其他功能:
void make_connections(int listenfd[6], Neighbor neighbor[6], struct sockaddr_in servAddr, fd_set read_set) {
int num_hosts = 6;
int i, rc, on=1;
struct sockaddr_storage their_addr;
socklen_t addr_size;
for (i=0; i<6; i++) {
// Create one socket for each neighbor
if((listenfd[i] = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
exit(1);
}
/*************************************************************/
/* Allow socket descriptor to be reuseable */
/*************************************************************/
rc = setsockopt(listenfd[i], SOL_SOCKET, SO_REUSEADDR,
(char *)&on, sizeof(on));
if (rc < 0)
{
perror("setsockopt() failed");
close(listenfd[i]);
exit(-1);
}
/*************************************************************/
/* Set socket to be non-blocking. All of the sockets for */
/* the incoming connections will also be non-blocking since */
/* they will inherit that state from the listening socket. */
/*************************************************************/
rc = ioctl(listenfd[i], FIONBIO, (char *)&on);
if (rc < 0)
{
perror("ioctl() failed");
close(listenfd[i]);
exit(-1);
}
/* get server IP address (input must be IP address, not DNS name) */
bzero(&servAddr,sizeof(servAddr)); //zero the struct
servAddr.sin_family = AF_INET; //address family (ipv4)
servAddr.sin_port = htons(neighbor.port); //sets port to network byte order
servAddr.sin_addr.s_addr = INADDR_ANY;
// first attempt to bind / listen on each port
if (bind(listenfd[i], (struct sockaddr *)&servAddr, sizeof(servAddr)) < 0) {
perror("bind failed");
exit (-1);
}
if (listen(listenfd[i], 10) < 0) {
perror("listen() failed");
exit (-1);
}
}
}
编辑2:很确定我想通了。我正在使用我的时间值 (tv) 对我的过程进行一些时间戳记。看起来那是无效参数的来源,而不是来自套接字。