我在线程中使用 select() 来监视数据报套接字,但除非在线程启动之前将数据发送到套接字,否则 select() 将继续返回 0。
我混合了一点 C 和 C++;这是启动线程的方法:
bool RelayStart() {
sock_recv = socket(AF_INET, SOCK_DGRAM, 0);
memset(&addr_recv, 0, sizeof(addr_recv));
addr_recv.sin_family = AF_INET;
addr_recv.sin_port = htons(18902);
addr_recv.sin_addr.s_addr = htonl(INADDR_ANY);
bind(sock_recv, (struct sockaddr*) &addr_recv, sizeof(addr_recv));
isRelayingPackets = true;
NSS::Thread::start(VIDEO_SEND_THREAD_ID);
return true;
}
停止线程的方法:
bool RelayStop() {
isSendingVideo = false;
NSS::Thread::stop();
close(sock_recv);
return true;
}
该方法在线程中运行:
void Run() {
fd_set read_fds;
int select_return;
struct timeval select_timeout;
FD_ZERO(&read_fds);
FD_SET(sock_recv, &read_fds);
while (isRelayingPackets) {
select_timeout.tv_sec = 1;
select_timeout.tv_usec = 0;
select_return = select(sock_recv + 1, &read_fds, NULL, NULL, &select_timeout);
if (select_return > 0 && FD_ISSET(sock_recv, &read_fds)) {
// ...
}
}
}
问题是,如果在调用 RelayStart() 之前没有进程已经将 UDP 数据包发送到端口 18902,则 select() 将始终返回 0。因此,例如,我无法在不重新启动线程的情况下重新启动发送方(以正确的顺序。)
只要首先启动发件人,一切似乎都可以正常工作。