【问题标题】:udp winsock programmingudp winsock 编程
【发布时间】:2010-10-05 04:53:14
【问题描述】:

我是套接字编程的初学者。我想从端口连续接收 udp 数据包。为此,我创建了套接字并使用了我在程序中完成的 bind 和 recv 调用。在缓冲区中,我存储 udp 数据包。如何逐包接收。如何为特定时间间隔设置条件?提前致谢。

static int recvData = 1;
sockID = socket(AF_INET, SOCK_DGRAM, 0);
 if(sockID < 0)
 {
  printf("Socket creation error\n");
        WSACleanup();
 }
 else
 {
  printf("Socket Created\n");
 }

 fepAddr.sin_family = AF_INET;
 fepAddr.sin_port = htons(inputData.portNo);
 fepAddr.sin_addr.s_addr = inet_addr(inputData.destIPAddr);

 if (bind(sockID, (struct sockaddr *)&fepAddr, sizeof(fepAddr)) == SOCKET_ERROR)
 {
  printf("bind() failed: %ld.\n", WSAGetLastError());
  closesocket(sockID);
  return 0;
 }

 else
 {
  printf("bind() is OK!\n");
 }

 memset(udpBuf,sizeof(udpBuf),0);
 while (recvData)
 {
  printf("receiving data\n");
  recvResult =  recvfrom( sockID, udpBuf, sizeof(udpBuf), 0,(struct sockaddr *)&fepAddr, &sock_len); 


  fprintf(udp, "%s", udpBuf);
  //fwrite(udpBuf, sizeof(udpBuf), 1, udp);
  recvData-- ;
 }
exit:
    if(udp) 
    {
         fclose(udp);
         udp = 0; 
    }

 //shutdown socket
 closesocket(sockID); 
 fclose(udp);

【问题讨论】:

    标签: udp winsock


    【解决方案1】:

    recvfrom() 逐包接收 UDP 数据。如果给定的数据包太大,recvfrom() 将返回错误。至于时序,可以通过 select() 来知道socket什么时候可读。

    试试这样的:

    sockID = socket(AF_INET, SOCK_DGRAM, 0); 
    if (sockID == INVALID_SOCKET) 
    { 
      printf("Socket creation error\n"); 
      goto exit;
    } 
    
    printf("Socket Created\n"); 
    
    memset(&fepAddr, 0, sizeof(fepAddr));
    fepAddr.sin_family = AF_INET; 
    fepAddr.sin_port = htons(inputData.portNo); 
    fepAddr.sin_addr.s_addr = inet_addr(inputData.destIPAddr); 
    
    if (bind(sockID, (struct sockaddr *)&fepAddr, sizeof(fepAddr)) == SOCKET_ERROR) 
    { 
      printf("bind() failed: %ld.\n", WSAGetLastError()); 
      goto exit;
    } 
    
    printf("bind() is OK!\n"); 
    
    memset(udpBuf, 0, sizeof(udpBuf)); 
    
    printf("receiving data\n"); 
    while (...) 
    {
      printf("."); 
    
      recvResult = recvfrom(sockID, udpBuf, sizeof(udpBuf), 0, (struct sockaddr *)&fepAddr, &addr_len);  
      if (recvResult == SOCKET_ERROR)
      {
        if (WSAGetLastError() != WSAEWOULDBLOCK)
        {
          printf("\nrecvfrom() failed: %ld.\n", WSAGetLastError()); 
          goto exit;
        }
    
        fd_set fd;
        FD_ZERO(&fd);
        FD_SET(sockID, &fd);
    
        timeval t;
        t.tv_sec = ...; // seconds
        t.tv_usec = ...; // microseconds
    
        selectResult = select(0, &fd, NULL, NULL, &t);
        if (selectResult == SOCKET_ERROR)
        {
          printf("\nselect() failed: %ld.\n", WSAGetLastError()); 
          goto exit;
        }
    
        if (selectResult == 0)
        {
          printf("\nsocket timed out.\n");
          goto exit;
        }
    
        continue;
      }
    
      if (recvResult > 0)
        fwrite(udpBuf, recvResult, 1, udp); 
    } 
    
    exit: 
      if (udp != 0)
      { 
        fclose(udp); 
        udp = 0;  
      } 
    
      if (sockID != INVALID_SOCKET) 
      {
        closesocket(sockID);  
        sockID = INVALID_SOCKET;
      }
    

    【讨论】:

    • 我需要更多帮助.....我已经使用 socket(PF_PACKET, SOCK_RAW, ETH_P_IP) 创建了原始套接字....但是它给出了无效的参数...如何创建原始套接字从端口接收 udp 数据包??
    • SOCK_RAW 在 PF_PACKET 系列中不可用。它仅在 AF_INET 和 AF_INET6 系列中可用。
    • 绑定成功,即使端口不可用。它返回零。什么原因???是否有任何标志可以设置绑定....请帮助我...
    • 在 Windows 上,如果将套接字绑定到通配符地址(即:ADDR_ANY),那么与 NIC 的物理绑定可能会在内部延迟,直到调用 listen(),在 bind() 之后很久退出。 bind() 在这种情况下不能报告错误。错误将来自 listen() 而不是。 MSDN 在 listen() 文档中对此进行了描述。另外,附带说明一下,从 XP SP2 开始的 SOCK_RAW 套接字上不允许使用 bind()。 MSDN 也记录了这一点。
    猜你喜欢
    • 1970-01-01
    • 2012-11-30
    • 1970-01-01
    • 1970-01-01
    • 2016-02-26
    • 2017-12-24
    • 1970-01-01
    • 2012-04-21
    • 2010-10-15
    相关资源
    最近更新 更多