select()函数经典错误

@select()函数经典错误

select()函数经典错误

最近调试一个板载WiFi模块,需要进行UDP通信,怎么调试都会出现 ***select fail:Invalid argument*** 这样的错误,查看代码又感觉没有什么问题,然后注意调试,最终发现,是 *struct timeval timeout;//定义slect超时结构体* 未进行初始化造成的。 由于函数 int select(int nfds, fd_set* readset, fd_set* writeset, fe_set* exceptset, struct timeval* timeout) 需要调用到 struct timeval* timeou结构体,在函数内定义的该结构体,局部变量未初始化,导致timeou内时间随机,因此select报错,程序如下。


/**************************************************************************
* 函数名称: int udp_set_rcv( int sfd, const struct sockaddr *toAddr,fd_set *fds)
* 功能描述: 非阻塞接收recvfrom udp参数接口 用于板载WiFi发送set设置数据用
* 输入参数:  sfd:创建socket的udp通道值	toAddr:发送到的socket结构体 ,fds 文件描述符集合
* 输出参数:
* 返 回 值: iResult 成功返回发送的参数指令的长度,失败返回-1 ,具体错误查看errno , 超时返回-2,说明没有参数返回,或者无通信
* 其它说明:
* 修改日期    版本号	 修改人		  修改内容
* -----------------------------------------------
* 2022/03/02	  V1.0		 ZhaoChengJie		   first commit
* 2022/03/03	  V1.1		 ZhaoChengJie		  add memset(&timeout, 0,sizeof(timeout)); 函数,缺少该函数导致select()报错,经典错误

**************************************************************************/
int udp_set_rcv( int sfd, const struct sockaddr *toAddr )
{
    struct sockaddr_in *pT_RcvAddr = (struct sockaddr_in *)toAddr ;
    int iResult=0;
    int iRcvAddrLen = 0 ;
    int iWatchDogTime = 0;
    char cMsg[1024] = {0};
    struct timeval timeout;//定义slect超时结构体
    fd_set fds; //定义一个文件描述符集合

    memset(&timeout, 0,sizeof(timeout));  //由于此处最开始未初始化,导致select()函数一直有问题!!!找了好久的bug!!!fuxk
    iRcvAddrLen = sizeof( struct sockaddr_in ) ;
#if PRINTF_ALL_PARA
    printf("sfd=%d\n", sfd );
#endif

    //循环监视文件描述符集合
    while(1)
    {
        iWatchDogTime ++ ;//看门狗
        timeout.tv_sec = MAX_BLOCK_TIME;
#if PRINTF_ALL_PARA
        printf("iWatchDogTime=%d--tv_sec=%d--usec=%d\n", iWatchDogTime, timeout.tv_sec, timeout.tv_usec);
#endif
        if( iWatchDogTime > MAX_WATCHDOG_TIME )
        {
            printf("dead loop socket , communication failure\n" );
            return -2;//通信未成功
        }

        FD_ZERO(&fds);//清空文件描述符集合
        FD_SET( sfd, &fds); //把网络通信文件描述符加入到集合中

        iResult = select(sfd+1,&fds,NULL,NULL,&timeout);//阻塞等待,直到集合中有活跃的描述符
#if PRINTF_ALL_PARA
        printf(" iResult select = %d\n", iResult );
#endif
        if(iResult < 0)//错误
        {
            perror(" select fail:");
            //close(sfd);
            return -1;
        }
        /*
        else if(iResult == 0)//超时
        {
        	perror("(nvram_set_SSID)select over time:");
        	close(sfd);
        }
        */
        else if(iResult > 0)  //有活跃的  ret为1
        {
#if PRINTF_ALL_PARA
            printf(" rcv new data\n" );
#endif
            if(FD_ISSET(sfd,  &fds))//判断是否是new_socket_fd活跃,(有消息收到)
            {
                iResult = recvfrom(sfd, cMsg, sizeof(cMsg), 0, (struct sockaddr *)pT_RcvAddr, &iRcvAddrLen );//接收回来的信息和IP信息
                if(iResult == -1)
                {
                    printf(" RecvData result=%d--%s\n", iResult, strerror ( errno )  );
                    return iResult;
                }
                printf(" [%s:%d]",inet_ntoa(pT_RcvAddr->sin_addr),ntohs(pT_RcvAddr->sin_port));//打印消息发送方的ip与端口号
                printf("msg=%s\n",cMsg	);
                return iResult;
            }
        }
        memset(cMsg, 0, sizeof(cMsg));//清空存留消息
        sleep(1);
    }
}

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值