linux下面select返回115错误

或者你会发现,你在编写程序时,不注意,或者一个很不起眼的写法,可它会给你带来很无奈的错误,让你很久才会发现,原来这个问题是这么回事。

1、常见的写法问题

1
2
3
4
5
6
7
8
9
fd_set fd;
FD_ZERO(&fd);
FD_SET( skt, &fd);
do
{
   int n = select( skt+1, &fd, 0,0, 0);
   if ( n == -1 ) break ;
   else if ( n > 0) break ;
} while ( true );

这个问题看似不怎么,根据原理select会重置参数,所以fd这个参数在调用完select之后会被更改,所以下次执行select必须重新设置fd,就是说要将 FD_ZERO(&fd); FD_SET( skt, &fd);放在do,while里面,即每次select都要先初始化fdset;

2、另外做超时时可能会出现115错误,linux下面使用常见错误,这个问题我也遇到过,发现是一个很犀利的写法

select最后一个参数是timeval指针,这个指针也需要和fd一样,在每次select都要重新设置,如下面代码

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//ERROR
timeval tv; tv.sec = 0;tv.usec = 10;
do
{
    fd_set fd; FD_ZERO(&fd); FD_SET(skt,&fd);
  int n =  select( skt + 1, &fd, 0,0, &tv ); //执行完这句tv就被置0了
  if ( n ==-1 || n>0) break ;
} while ( true );
//OK
do
{
    timeval tv; tv.sec = 0;tv.usec = 10;
    fd_set fd; FD_ZERO(&fd); FD_SET(skt,&fd);
  int n =  select( skt + 1, &fd, 0,0, &tv ); //执行完这句tv就被置0了
  if ( n ==-1 || n>0) break ;
} while ( true );

这是我在写一个超时计算代码时发现的问题,有一个函数发送数据,需要在指定的时间内发送完,如果超过时间就返回真实发送长度。

那么,你可能需要在多次send之间来计算哪些是超时的,假如我传一个30秒的超时,你不能只select一次,将时间设置为超时,因为这样有问题,就是在第一次select成功之后,在send的时候可能没有发送完所有数据,还要不断的发送,在再次发送时超时就不好计算了,因为你上次select用的30秒,把时间用光了,并且你也不知道select到底用了多少时间。

我们可以将30秒划分为几个小的秒单位,比较每次select用1秒的时间,这样每次select或send超时都计1秒时间 ,在不断的累加就可以了。刚好在累加的时候如果你把timeval参数写在 do,while外面

那么只有第一次是正常的,第二次timeval变成 tv.sec = 0,tv.usec = 0;这样会造成select超时计算失误,因为tv值0表示不等待直接返回,假如此时发送缓冲已满,立马返回超时,这样你累加1秒时间就不准。

 

我当时测试 的是,设置30秒,结果只等 了一秒就返回超时了,打印日志显示select返回0确实是有30次,可是除了第一次有延迟,后面的基本上是同时显示出来的,就说明后面select根本没有等待,后来发现这个timeval被置0了,我呢个去,不发现不知道,一发现太肯我了。

除声明外, 跑步客文章均为原创,转载请以链接形式标明本文地址

本文地址:   http://www.paobuke.com/develop/c/pbk1371.html

当在Linux系统中使用socket读取数据时,如果返回-115错误,通常表示接收缓冲区空间不足的错误。 当你使用socket函数创建套接字并进行数据传输时,内核会为每个套接字分配接收缓冲区,用于存储接收到的数据。如果接收缓冲区已满,而继续接收数据,则会导致缓冲区溢出,数据丢失或覆盖。 -115错误常见于非阻塞模式的套接字操作。在非阻塞模式下,读操作会立即返回,并不会等待数据准备好。而当接收缓冲区为空时,读操作尝试读取数据会返回-115错误。 如果你遇到这个错误,你可以通过以下方法解决: 1. 增加接收缓冲区大小:通过修改套接字选项,可以增加接收缓冲区的大小。可以使用setsockopt函数来设置SO_RCVBUF选项,将缓冲区大小增加到你需要的大小。 2. 使用非阻塞模式的循环读取:可以使用非阻塞模式,并在循环中进行读取操作。当返回-115错误时,可以继续循环等待数据准备好,并进行读取。 3. 使用select或epoll函数进行异步IO操作:这些函数可以用于监视套接字文件描述符,当有数据可读时再进行读取操作,避免出现接收缓冲区空间不足的错误。 总之,linux socket读取数据返回-115错误通常是由于接收缓冲区空间不足引起的。通过增大接收缓冲区大小、使用非阻塞模式的循环读取或使用异步IO操作等方法,可以解决这个问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值