[英]C / select reads only from one file descriptor
new day, new problems. 新的一天,新的问题。 Somehow I find myself asking questions here almost every day, btw. 不知何故,我发现自己几乎每天都在这里提问,顺便说一句。 thanks for your support so far. 感谢您的支持到目前为止。 I implemented the select
to read from four file descriptors, but it does only read from one. 我实现了select
来从四个文件描述符中读取,但它只从一个读取。
I have a test application sending packets on all four ports to the second machine, where the C program is running: 我有一个测试应用程序将所有四个端口上的数据包发送到运行C程序的第二台机器:
data_packet to port[13501]
data_packet to port[13502]
data_packet to port[13503]
data_packet to port[13504]
data_packet to port[13501]
and so on... 等等...
Using tcpdump
I can see, that the test application is working correctly: 使用tcpdump
我可以看到测试应用程序正常工作:
08:02:26.391843 IP 10.1.1.2.2000 > 10.1.1.40.13501: UDP, length: 28
08:02:27.391794 IP 10.1.1.2.2000 > 10.1.1.40.13502: UDP, length: 28
08:02:28.391820 IP 10.1.1.2.2000 > 10.1.1.40.13503: UDP, length: 28
08:02:29.391918 IP 10.1.1.2.2000 > 10.1.1.40.13504: UDP, length: 28
But my application just reads from one FD (socket), in the beginning I show all available file descriptors inside the fd_set
: 但是我的应用程序只是从一个FD(套接字)读取,在开始时我在fd_set
显示所有可用的文件描述符:
thread 1 started, pc_packet_receiver
thread 2 started, pc_packet_sender
sock_fd[9]
sock_fd[10]
sock_fd[11]
sock_fd[12]
received on sock_fd[12] on ETH0 on port 13503
received on sock_fd[12] on ETH0 on port 13503
received on sock_fd[12] on ETH0 on port 13503
received on sock_fd[12] on ETH0 on port 13503
[ctrlC] sockets closed, threads stopped...
The implementation around the select
looks like the following: select
周围的实现如下所示:
FD_SET(sock_fd[i], &read_fds);
fdmax = sock_fd[i];
}
for(i = 0; i < 4; i++) {
printf("sock_fd[%d]\n",sock_fd[i]);
}
while(keepRunning) {
bzero(&incoming_msg, MAX_PAYLOAD_LEN);
bzero(&outgoing_msg, MAX_PAYLOAD_LEN);
bzero(&peer, peer_len);
readsocks = select(fdmax+1, &read_fds, NULL, NULL, NULL);
if (readsocks < 0) {
perror("select");
exit(EXIT_FAILURE);
} else if (readsocks == 0) {
printf("nothing to read from\n");
continue;
}
for(i = 0; i < 4; i++) {
if(FD_ISSET(sock_fd[i], &read_fds)) {
in_msg_len = recvfrom(sock_fd[i],
incoming_msg,
MAX_PAYLOAD_LEN,
0,
(struct sockaddr *) &client_addr,
&sock_len_client);
if (in_msg_len < 0) {
perror("failed to receive data\n");
exit(EXIT_FAILURE);
}
strncpy(outgoing_msg, incoming_msg, in_msg_len);
if(getsockname(sock_fd[i], &peer, &peer_len) < 0) {
perror("getsockname() failed");
return (-1);
}
receiving_eth_port = (int)ntohs(peer.sin_port);
#if DBG_OUTPUT
printf("received on sock_fd[%d] on ETH0 on port %d\n", sock_fd[i], receiving_eth_port);
#endif
how can I achieve that select
reads from all sockets...? 我如何实现从所有套接字中select
读取...?
select()
alters your read_fds
! select()
改变你的read_fds
!
After the first call to select()
, read_fds
may only have one fd bit set, and you're hence checking only for this file descriptor in all remaining loops. 在第一次调用select()
, read_fds
可能只设置了一个fd位,因此您只检查所有剩余循环中的此文件描述符。
The solution is to re-build read_fds
every time before calling select()
. 解决方案是每次调用select()
之前重新构建read_fds
。 This may sound tedious, but it's common practice when dealing with select()
. 这可能听起来很乏味,但在处理select()
时这是常见的做法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.