67-套接字超时(select)

设置超时的第二个技术是使用 select 函数。它使用了 select 函数的最后一个超时参数,对套接字描述符进行了“预读”。

1. 程序路径

代码托管在 gitos 上,请使用下面的命令获取:

git clone https://git.oschina.net/ivan_allen/unp.git

如果你已经 clone 过这个代码了,请使用 Git pull 更新一下。本节程序所使用的程序路径是 unp/program/advcio/read_timeo/read_timeo_select.

2. 伪代码

  • 用于判断是否可读的函数
// 该函数利用 select 函数判断在 nsec 时间内描述符 fd 是否可读
int readable_timeo(int fd, int nsec) {
  int ret;
  fd_set rfds;
  struct timeval tv;

  FD_ZERO(&rfds);
  FD_SET(fd, &rfds);

  tv.tv_sec = nsec;
  tv.tv_usec = 0;

  ret = select(fd + 1, &rfds, NULL, NULL, &tv);

  return ret;
}
  • 带超时的 recvfrom 函数
int recvfrom_timeo(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen, int nsec) {
  int ret;

  ret = readable_timeo(sockfd, nsec);

  // select 函数返回 0,表示超时
  if (ret == 0) {
    errno = ETIMEDOUT;
    ret = -1;
  }
  else {
    ret = recvfrom(sockfd, buf, len, flags, src_addr, addrlen);
  }

  return ret;
}

3. 实验结果

read_timeo_select 是一个 udp 客户端,实际上就是前面的 udp/basic 程序,只不过它将 recvfrom 修改成了带超时的 recvfrom.

read_timeo_select 向 mars 主机发送了一个报文后,阻塞在 recvfrom_timeo 函数上,因为 mars 主机上的服务器并未启动,因此 read_timeo_select 永远也不可能收到 mars 主机发回的数据。

经历 5 秒的时候后,recvfrom_timeo 函数超时返回。


这里写图片描述
图1 带超时的 recvfrom 函数

4. 总结

  • 掌握使用 select 函数编写超时函数的方法
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值