我在arm linux平台上有一个关于select()的问题,一侧是arm linux作为tcp客户端,另一侧是pc作为tcp服务器。 tcp客户端连接到服务器并以固定的间隔时间(例如5ms)从服务器接收数据。大多数情况下,select工作正常,但有时会发生奇怪的事情,函数select()连续返回零(超时),之后select返回正常,但读取数据的大小异常,如下图。
有人知道原因吗?非常感谢。
while(scan->is_child_thread_active)
{
FD_ZERO(&read_fd);
w_time.tv_sec = 0;
w_time.tv_usec = (100*1000);//100ms
if (scan->tcp_socket_fd > 0)
{
FD_SET(scan->tcp_socket_fd, &read_fd);
}
else
{
break;
}
mxfd = scan->tcp_socket_fd;
if ((n_ready=select(mxfd + 1, &read_fd, (fd_set *) NULL, (fd_set *) NULL, &w_time)) < 0 )
{
print_err("select error: %s \n", strerror(errno));
close(scan->tcp_socket_fd);
scan->tcp_socket_fd = -1;
continue;
}
if (0x00 == n_ready )
{
print_err("select timeout \n");
continue;
}
scan->handleSocketRead(scan, read_fd, scan->tcp_socket_fd);
}
读取句柄编码如下
if (sock_fd > 0 && FD_ISSET(sock_fd, &read_fd_set))
{
if ((n_read = recv(sock_fd, scan->tcp_buffer_, TCP_BUF_SZ, 0))<=0)
{
print_err("read tcp error,fd= %d:%s\n", sock_fd, strerror(errno));
close(sock_fd);
sock_fd = -1;
return;
}
curr_data_time_ = get_ms_time_pf();
RBT_MS_T delta_time = curr_data_time_ - last_data_time_;
printf("rcv data len %d , delta time = %llu\n", n_read, delta_time);
scan->writeBufferBack(scan->tcp_buffer_, n_read);
while( scan->handleNextPacket() ) {}
last_data_time_ = get_ms_time_pf();
}
顺便说一句,该板在arm core freescale imx6q下运行。下图中最长的卡住时间超过1秒,其他日志显示时间有时会持续5秒甚至更长。
linux配置有问题吗?
最佳答案
每the POSIX select()
documentation :
RETURN VALUE
Upon successful completion, the
pselect()
andselect()
functions shall return the total number of bits set in the bit masks. Otherwise, -1 shall be returned, and errno shall be set to indicate the error.
零是完全合法的结果,意味着文件描述符上没有检测到事件。
不保证网络流量顺利传递。如果这对您的使用造成问题,您需要解决网络问题,因为代码没有问题。
关于c - 为什么select()有时连续返回0,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55118783/