一块vxworks中的一片老代码,tftp client在调用tftpsend的时候,陷入死循环,代码很简单,如下:
- FOREVER
- {
- TFTP_MSG trash;
- if (ioctl (pTftpDesc->sock, FIONREAD, (int)&amount) == ERROR)
- return (ERROR);
- if (amount == 0) /* done - socket cleaned out */
- break;
- (void) recvfrom (pTftpDesc->sock, (caddr_t) &trash, sizeof
- (TFTP_MSG), 0, (SOCKADDR *) NULL, (int *) NULL);
- }
- /* break out to send loop in order to resynch by reresending */
- if (ntohs (pTftpReply->th_block) == (blockReply - 1))
- break;
- return (ERROR); /* things look bad - return */
- }
代码中,先通过ioctl看看sock中到底有多少数据可读,如果可读,再调用recvfrom真正的读取数据。但是在我们的设备中,发现ioctl返回成功,并且amount肯定大于0,但是recvfrom的时候,却返回了ERROR,于是悲剧性地死循环了。
看看源代码,发现以FIONREAD调用ioctl时,并没有检查socket状态,只是取回接收缓存中的字节数,而recvfrom会检查状态,可能会返回失败,或者接收不到数据,当然recvfrom在处理socket状态时,处理比较复杂,这里想说的是前面两种情况并不是完全一一对应的关系:即并不一定是接收缓存中有数据,调用recvfrom就能够接收。源代码中没有处理recvfrom返回值,导致出现死循环,在vxworks的后续版本(6.x)已经修改为检查返回值,如果出错,就要退出循环。
- if (recvfrom (pTftpDesc->sock, (caddr_t) &trash,
- sizeof (TFTP_MSG), 0, (struct sockaddr *) NULL,
- (int *) NULL) == ERROR)
- return (ERROR);
阅读(2652) | 评论(0) | 转发(0) |