主题 : 套接字sockt超时设置 复制链接 | 浏览器收藏 | 打印
级别: 新手上路
UID: 87922
精华: 0
发帖: 4
金钱: 20 两
威望: 4 点
贡献值: 0 点
综合积分: 8 分
注册时间: 2013-03-01
最后登录: 2013-05-13
楼主  发表于: 2013-05-13 23:06

 套接字sockt超时设置

我想设置一个超时,当设置套接字阻塞,代码如下
//创建套接字
    SOCKET sockSrv=socket(AF_INET,SOCK_DGRAM,0);
    SOCKADDR_IN addrSrv;
    addrSrv.sin_family=AF_INET;
    addrSrv.sin_port=htons(69);//默认的TPFP端口
    addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);//本机的任意一个IP
    if(bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR))<0)//绑定到本地的一个IP和地址,注意第二个参数不要写成(SOCKADDR*)&sockSrv,
    {
        printf("绑定失败!");
        exit(1);
    }
    //初始化远程地址信息
    sockaddr_in addrClient;
    char SendBuf[1030];
    char SendBuf1[1030];
    char RecvBuf[1030];
    char endfile=0;
    char State=STATE_TRANSFER_OVER;
    //char *FileBuf=new char[1024];
    //接收数据,定义数据块大小为512字节
    int alen = sizeof(addrClient);
    int recvbuflen;
    int sendbuflen=-1;
    int sendbuflen1;
    int equal;
    char *ptr=NULL;
    short block_Num=1;
    short tu_block;
    FILE *fd=NULL;
    char FileName[31]="NANDFlash\\example\\";
    int k;
    struct timeval tv_out;
    tv_out.tv_sec = 1;//等待s
    tv_out.tv_usec = 0;//us
    int j=setsockopt(sockSrv,SOL_SOCKET,SO_RCVTIMEO,(char*)&tv_out, sizeof(tv_out));//第3个参数SO_RCVTIMEO是接收超时
    if (j==SOCKET_ERROR)
    {
         k=WSAGetLastError();
    }
    while (1)
    {          
        recvbuflen=recvfrom(sockSrv,RecvBuf,1030,0,(SOCKADDR*)&addrClient,&alen);
        if (SOCKET_ERROR==recvbuflen)//1s的超时到,没有收到包
        {
            //wprintf(L"recvfrom failed with error: %d\n", WSAGetLastError());
            if(10060==WSAGetLastError())//超时
            {
                if (STATE_TRANSFER==State)//文件传输中
                {

                    //int error=sendto(sockSrv,SendBuf1,sendbuflen1,0,(sockaddr*)&addrClient,alen);
                    int error=sendto(sockSrv,SendBuf,sendbuflen1,0,(sockaddr*)&addrClient,alen);//注意这里只能是缓冲,缓冲只存包含文件内容的包,sendbuflen1为sendbuflen的缓存,
                    //sendbuflen每次发送完赋值为-1;                  
                    printf("数据包位数%d\n",sendbuflen1);
                    if(error>0)
                    {
                        printf("重发数据包%d\n",block_Num);
                
                    }
                    if(error==SOCKET_ERROR)
                    {
                        wprintf(L"sendto failed with error: %d\n", WSAGetLastError());
                    }
                }
            }
        }
我写的是VS2005的移动智能设备应用程序,setsockopt函数显示错误100042,
然后我换一个非阻塞方式实现超时
unsigned long flag=1;
    int j=ioctlsocket(sockSrv,FIONBIO,&flag);//套接字为非阻塞
    if (j==SOCKET_ERROR)
    {
         k=WSAGetLastError();
    }
    while (1)
    {          
        while (timeout--)
        {
            recvbuflen=recvfrom(sockSrv,RecvBuf,1030,0,(SOCKADDR*)&addrClient,&alen);
            if (recvbuflen>0)
              {  
                  timeout=TIME_OUT;
                  break;
              }
        }
        
        if (SOCKET_ERROR==recvbuflen)//1s的超时到,没有收到包
        {
            //wprintf(L"recvfrom failed with error: %d\n", WSAGetLastError());
            timeout=TIME_OUT;
            int m=WSAGetLastError();
            if(10035==WSAGetLastError())//没有读到数据
            {
                if (STATE_TRANSFER==State)//文件传输中
                {

                    //int error=sendto(sockSrv,SendBuf1,sendbuflen1,0,(sockaddr*)&addrClient,alen);
                    int error=sendto(sockSrv,SendBuf,sendbuflen1,0,(sockaddr*)&addrClient,alen);//注意这里只能是缓冲,缓冲只存包含文件内容的包,sendbuflen1为sendbuflen的缓存,
                    //sendbuflen每次发送完赋值为-1;                  
                    printf("数据包位数%d\n",sendbuflen1);
                    if(error>0)
                    {
                        printf("重发数据包%d\n",block_Num);
                
                    }
                    if(error==SOCKET_ERROR)
                    {
                        //wprintf(L"sendto failed with error: %d\n", WSAGetLastError());
                        int u=WSAGetLastError();
                    }
                }
            }
        }
这次sendto()函数出现错误10047,崩溃了求大神指点