Chinaunix首页 | 论坛 | 博客
  • 博客访问: 527617
  • 博文数量: 118
  • 博客积分: 2575
  • 博客等级: 大尉
  • 技术积分: 1263
  • 用 户 组: 普通用户
  • 注册时间: 2009-09-27 09:37
文章分类

全部博文(118)

文章存档

2017年(11)

2016年(8)

2015年(1)

2014年(9)

2013年(7)

2012年(38)

2011年(14)

2010年(18)

2009年(12)

分类: C/C++

2012-06-14 10:45:34

一块vxworks中的一片老代码,tftp client在调用tftpsend的时候,陷入死循环,代码很简单,如下:

点击(此处)折叠或打开

  1. FOREVER
  2.         {
  3.           TFTP_MSG    trash;

  4.          if (ioctl (pTftpDesc->sock, FIONREAD, (int)&amount) == ERROR)
  5.          return (ERROR);

  6.          if (amount == 0)        /* done - socket cleaned out */
  7.          break;

  8.      (void) recvfrom (pTftpDesc->sock, (caddr_t) &trash, sizeof
  9.                   (TFTP_MSG), 0, (SOCKADDR *) NULL, (int *) NULL);
  10.      }

  11.      /* break out to send loop in order to resynch by reresending */

  12.      if (ntohs (pTftpReply->th_block) == (blockReply - 1))
  13.      break;

  14.      return (ERROR);            /* things look bad - return */
  15.      }
代码中,先通过ioctl看看sock中到底有多少数据可读,如果可读,再调用recvfrom真正的读取数据。但是在我们的设备中,发现ioctl返回成功,并且amount肯定大于0,但是recvfrom的时候,却返回了ERROR,于是悲剧性地死循环了。

看看源代码,发现以FIONREAD调用ioctl时,并没有检查socket状态,只是取回接收缓存中的字节数,而recvfrom会检查状态,可能会返回失败,或者接收不到数据,当然recvfrom在处理socket状态时,处理比较复杂,这里想说的是前面两种情况并不是完全一一对应的关系:即并不一定是接收缓存中有数据,调用recvfrom就能够接收。源代码中没有处理recvfrom返回值,导致出现死循环,在vxworks的后续版本(6.x)已经修改为检查返回值,如果出错,就要退出循环。

点击(此处)折叠或打开

  1. if (recvfrom (pTftpDesc->sock, (caddr_t) &trash,
  2.                           sizeof (TFTP_MSG), 0, (struct sockaddr *) NULL,
  3.                           (int *) NULL) == ERROR)
  4.                           return (ERROR);


阅读(2652) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~