void CNewClientDlg::GetPdListUdp()
{ SOCKET socket1;

WORD VersionRequested;
WSADATA WsaData;
VersionRequested=MAKEWORD(2,2);
WSAStartup(VersionRequested,&WsaData); //启动WinSock2

struct sockaddr_in server;
int len =sizeof(server);
server.sin_family=AF_INET;
server.sin_port=htons(18848);          ///server的监听端口
CString vppserver="59.53.48.219";
server.sin_addr.s_addr=inet_addr(vppserver); ///server的地址 
int nTimeOver=5000;                       //这里设置超时的值
socket1=socket(AF_INET,SOCK_DGRAM,0); unsigned   long   ul   =   1;   
int iRet   =   ioctlsocket(socket1,   FIONBIO,   &ul);
setsockopt(socket1, SOL_SOCKET, SO_RCVTIMEO, (char*)&nTimeOver, sizeof(nTimeOver));
struct   timeval   timeout;     
fd_set   r;     

FD_ZERO(&r);     
FD_SET(socket1,   &r);     
timeout.tv_sec   =   3;   //连接超时3秒     
timeout.tv_usec   =0;     
int bb(0); while(TRUE && bb<30)
{

if (socket1)
{
// 包
if( ! m_ChannelTree.GetRootItem() )
{
m_LastPdOrder = 0; // 将保存上次频道的端口清空 // 第一次发送
UDPLOG  udplog;
memset((char*)&udplog , 0 , sizeof(udplog) );
udplog.packtype.type = 100 ;
udplog.udppack.orderPD = 0  ;

if (sendto(socket1, (char*)&udplog , sizeof(udplog),
0,(struct sockaddr*)&server,len)!=SOCKET_ERROR)
{
UDPPDLIST  UdpPdList;
int retval;
memset((char*)& UdpPdList, 0, sizeof(UdpPdList) );
switch(select(socket1,   0,   &r,   0,   &timeout)) 
{
case -1:
break;
case 0:
break;
default:
{
// 接收频道列表包
retval=recvfrom(socket1, (char*)&UdpPdList, sizeof(UdpPdList) ,
0,(SOCKADDR*)&server,&len );

TRACE("retval= %d   3735\n", retval);
if(retval == sizeof(UDPPDLIST) 
&& UdpPdList.packheader.type == 200 )
{
if(UdpPdList.padata.orderPd != -1 )
{

// 保存频道的编号
m_LastPdOrder = UdpPdList.padata.orderPd;


// 插入到树形控件中
InsetrTree(UdpPdList);

}
else
{
// 频道已经发送完毕,跳出循环并启动定时器
SetTimer(UdpGetPdList, 1000,NULL);
// SetTimer(UdpGetPdList, 1000*60,NULL);
goto lea;
}
}

}
}


}
else
{
//重新发送 
sendto(socket1, (char*)&udplog , sizeof(udplog),
0,(struct sockaddr*)&server,len);
}
}
else
{
// 得到最后一个频道的编号  m_LastPdOrder
// 开始组包

UDPLOG  udplog;
memset((char*)&udplog , 0 , sizeof(udplog) );
udplog.packtype.type = 100 ;
udplog.udppack.orderPD = m_LastPdOrder  ;

if (sendto(socket1, (char*)&udplog , sizeof(udplog),
0,(struct sockaddr*)&server,len)!=SOCKET_ERROR)
{

UDPPDLIST  UdpPdList;
int retval;
memset((char*)& UdpPdList, 0, sizeof(UdpPdList) );


switch(select(socket1,   0,   &r,   0,   &timeout)) 
{
case -1:
break;
case 0:
break;
default:
{
// 接收频道列表包
retval=recvfrom(socket1, (char*)&UdpPdList, sizeof(UdpPdList) ,
0,(SOCKADDR*)&server,&len );

TRACE("retval= %d   3788\n", retval);

if(retval == sizeof(UDPPDLIST) 
&& UdpPdList.packheader.type == 200 )
{
if(UdpPdList.padata.orderPd != -1 )
{
// 保存频道的编号
m_LastPdOrder = UdpPdList.padata.orderPd;

// 插入到树形控件中,
InsetrTree(UdpPdList);

}
else
{
// 频道已经发送完毕,跳出循环并启动定时器
SetTimer(UdpGetPdList, 1000,NULL);
// SetTimer(UdpGetPdList, 1000*60,NULL);
goto lea;
}

}


}
}

}
else
{
//重新发送 
sendto(socket1, (char*)&udplog , sizeof(udplog),
0,(struct sockaddr*)&server,len);
}
}

}
bb++;
}lea :
closesocket(socket1);}

解决方案 »

  1.   

    int iRet   =   ioctlsocket(socket1,   FIONBIO,   &ul);
    我把这句注释掉就可以接收到数据,但是socket就变成了阻塞模式了
      
         代码没有调整好,让大家看起来不方便,不好意思。
      

  2.   

    不知道这样对不对
    SOCKET socket1;

    WORD VersionRequested;
    WSADATA WsaData;
    VersionRequested=MAKEWORD(2,2);
    WSAStartup(VersionRequested,&WsaData); //启动WinSock2

    struct sockaddr_in server;
    int len =sizeof(server);
    server.sin_family=AF_INET;
    server.sin_port=htons(18848);          ///server的监听端口
    CString vppserver="59.53.48.219";
    server.sin_addr.s_addr=inet_addr(vppserver); ///server的地址 
    int nTimeOver=5000;                       //这里设置超时的值
    socket1=socket(AF_INET,SOCK_DGRAM,0); unsigned   long   ul   =   1;   
    int iRet   =   ioctlsocket(socket1,   FIONBIO,   &ul);
    setsockopt(socket1, SOL_SOCKET, SO_RCVTIMEO, (char*)&nTimeOver, sizeof(nTimeOver));
    struct   timeval   timeout;     
    fd_set   r;     

    FD_ZERO(&r);     
    FD_SET(socket1,   &r);     
    timeout.tv_sec   =   3;   //连接超时3秒     
    timeout.tv_usec   =0;     
    int bb(0); while(TRUE && bb<30)
    {

       if (socket1)
       {
          // 包
          if( ! m_ChannelTree.GetRootItem() )
          {
    m_LastPdOrder = 0; // 将保存上次频道的端口清空 // 第一次发送
    UDPLOG  udplog;
    memset((char*)&udplog , 0 , sizeof(udplog) );
    udplog.packtype.type = 100 ;
    udplog.udppack.orderPD = 0  ;

    if (sendto(socket1, (char*)&udplog , sizeof(udplog),
    0,(struct sockaddr*)&server,len)!=SOCKET_ERROR)
    {
        UDPPDLIST  UdpPdList;
        int retval;
        memset((char*)& UdpPdList, 0, sizeof(UdpPdList) );

        select(0,&r,NULL,NULL,&timeout);   
        FD_ISSET(socket1,&r)   ;
        // 接收频道列表包

        retval=recv(socket1,(char*)&UdpPdList,sizeof(UdpPdList),0);

        TRACE("retval= %d   3735\n", retval);
        if(retval == sizeof(UDPPDLIST) 
    && UdpPdList.packheader.type == 200 )
        {
    if(UdpPdList.padata.orderPd != -1 )
    {
                           // 保存频道的编号
        m_LastPdOrder = UdpPdList.padata.orderPd;              // 插入到树形控件中
                 InsetrTree(UdpPdList);
                               }
    else
    {
    // 频道已经发送完毕,跳出循环并启动定时器
                SetTimer(UdpGetPdList, 1000 * 5,NULL);
                                   goto lea;
    }
         }
    }
    else
    {
      //重新发送 
      sendto(socket1, (char*)&udplog , sizeof(udplog),
    0,(struct sockaddr*)&server,len);
    }
          }
          else
          {
             // 开始组包
    UDPLOG  udplog;
    memset((char*)&udplog , 0 , sizeof(udplog) );
    udplog.packtype.type = 100 ;
    udplog.udppack.orderPD = m_LastPdOrder  ;
    if (sendto(socket1, (char*)&udplog , sizeof(udplog),
         0,(struct sockaddr*)&server,len)!=SOCKET_ERROR)
    {
      UDPPDLIST  UdpPdList;
      int retval;
      memset((char*)& UdpPdList, 0, sizeof(UdpPdList) );   select(0,&r,NULL,NULL,&timeout); 
      FD_ISSET(socket1,&r)  ;
               // 接收频道列表包
      retval=recv(socket1,(char*)&UdpPdList,sizeof(UdpPdList),0);
      TRACE("retval= %d   3788\n", retval);

      if(retval == sizeof(UDPPDLIST) 
    && UdpPdList.packheader.type == 200 )
      {
         if(UdpPdList.padata.orderPd != -1 )
         {
    // 保存频道的编号
    m_LastPdOrder = UdpPdList.padata.orderPd;
    // 插入到树形控件中,
    InsetrTree(UdpPdList);
         }
         else
         {
            // 频道已经发送完毕,跳出循环并启动定时器
    SetTimer(UdpGetPdList, 1000 * 5,NULL);
    goto lea;
         }

       }
             }
    else
             {
      //重新发送 
      sendto(socket1, (char*)&udplog , sizeof(udplog),
    0,(struct sockaddr*)&server,len);
    }
           }
      }
    bb++;
             }lea :
    closesocket(socket1); TRACE(" 3875  \n");}