小花笑薇薇 2017-08-17 08:37 采纳率: 0%
浏览 4365

LWIP下,TCP接收数据过程中插拔网线,sock未非阻塞状态,但RECV堵塞

各位大神。。。帮帮我呗。。。我特别困惑

我在STM32F2系列下用select方式开发TCP服务端,每个服务端可以接收多个链接,
我每个链接都设置成了非阻塞模式,在TCP通讯过程中反复插拔网线,偶尔会出现SELECT任务被挂起的情况,我加了mark,在recv前的mark = recv后mark+1,然后任务被挂起。。。。请帮帮我

  • 写回答

2条回答 默认 最新

  • 小花笑薇薇 2017-08-17 08:39
    关注

    我的具体代码如下:
    if(s_NetRunFlag == 0)
    {
    Net_Initialize();
    // allocate a socket
    ts_sock_m = socket(AF_INET, SOCK_STREAM, 0);
    if (ts_sock_m < 0)
    {
    return; // Couldn’t Allocate a TCP Socket
    }

      // Bind the socket to the local port number and IP address
      memset(&sin, 0, sizeof(sin));
      sin.sin_family = AF_INET;
      sin.sin_port = htons(net_astIp[0].port_no);      
      // port number in network byte order
      memcpy((int8_t *)&sin.sin_addr, (int8_t *)net_astIp[0].ip_server_address, 4);
      if (bind(ts_sock_m, (const struct sockaddr *)&sin, sizeof(sin)) < 0)
      {
        closesocket(ts_sock_m);
        return; // Bind Failed
      }
    
      if (listen(ts_sock_m, NET_MAX_LINK) != 0) // 2 slave ports
      {
        closesocket(ts_sock_m);
        return; // Listen Failed
      }
    
      /*设置非阻塞模式*/
    
      ioctlsocket(ts_sock_m,FIONBIO,&nMode);
    
      FD_ZERO(&rset);
      FD_ZERO(&allset);   
      FD_SET(ts_sock_m, &rset);  
      maxfd = ts_sock_m; 
    
      timeout.tv_sec = 30;
      timeout.tv_usec = 0;
    
      s_NetRunFlag = 1;
    }
    
    while (1)
    {
      FD_ZERO(&rset);
      FD_SET(ts_sock_m, &rset);
      for (i = 0; i < NET_MAX_LINK; i++)  
      {  
        if (net_astRecv0[i].ts_sock_s != -1)  
        {  
          FD_SET(net_astRecv0[i].ts_sock_s, &rset);  
        }  
      }
    
      iSelectRet = select(maxfd + 1, &rset, NULL, NULL, &timeout);
      if(iSelectRet < 0)
      {/*错误*/
        yj_slect_err++;
        continue;
      }
      else if(iSelectRet == 0)
      {/*超时*/
        yj_slect_0++;
        for (i = 0; i <= maxi; i++) 
        {  
          ts_sock_s = net_astRecv0[i].ts_sock_s; 
          if(ts_sock_s >= 0)
          {/*文件描述符不大于0*/
            closesocket(ts_sock_s);
            FD_CLR(net_astRecv0[i].ts_sock_s, &rset);
            net_astRecv0[i].ts_sock_s = -1;
            net_astRecv0[i].ulTaskId = 0;
          }
        }
        maxi = 0;
        continue;
      }
      else
      {
        yj_slect_OK++;
        for (i = 0; i <= maxi; i++) 
        {  
          ts_sock_s = net_astRecv0[i].ts_sock_s;  
    
          if (FD_ISSET(ts_sock_s, &rset)) 
          {/*有链接则接收数据*/
            yj_recv_start++;
            n_received = recv(ts_sock_s, (int8_t *)stNetMsg.aucData, sizeof(stNetMsg.aucData), 0);
            if (n_received <= 0)
            {
              closesocket(ts_sock_s);
              FD_CLR(net_astRecv0[i].ts_sock_s, &rset);
              net_astRecv0[i].ts_sock_s = -1;
              net_astRecv0[i].ulTaskId = 0;
              yj_err_message[yj_recv_err] = n_received;
              yj_recv_err++;
    
            }
            else
            {
              yj_recv++;
              stNetMsg.usLength = n_received;          
              stNetMsg.ulTaskId = net_astRecv0[i].ulTaskId;
              stNetMsg.ucRtNum = i;
              stNetMsg.ucLtNum = NET_LISTEN_TASK0;
    
              if ((stNetMsg.usLength > 7) && 
                  (stNetMsg.aucData[2] == 0x00) && 
                    (stNetMsg.aucData[3] == 0x00))
              {
                memcpy(&usLen, stNetMsg.aucData + 4, 2);
                if (usLen == (unsigned short)(stNetMsg.usLength - 6))
                {
                  xQueueSend(xCtrlQueueHandle, &stNetMsg, 0);
                }
              }
            }                   
          }  
        }
    
        if (FD_ISSET(ts_sock_m, &rset))
        {/*创建新的链接*/
          yj_acceptstart++;
          sin_len = sizeof(struct sockaddr_in);
          ts_sock_s = accept(ts_sock_m, (struct sockaddr *)&sin, (socklen_t *)&sin_len);
          yj_accept++;
          if (ts_sock_s == -1)  
          {
            continue;
          }
    
          /*设置非阻塞模式*/
          nMode = 1;
          ioctlsocket(ts_sock_s,FIONBIO,&nMode);
    
          for (i = 0; i < NET_MAX_LINK; i++) 
          {  
            if (net_astRecv0[i].ts_sock_s < 0) 
            {  
              net_astRecv0[i].ts_sock_s= ts_sock_s;  
              if (i > maxi)  
                maxi = i;  
              break;  
            }   
          }  
          if (ts_sock_s > maxfd)  
            maxfd = ts_sock_s;  
        }
      }
      osDelay(1);
    }
    

    }

    评论

报告相同问题?

悬赏问题

  • ¥15 素材场景中光线烘焙后灯光失效
  • ¥15 请教一下各位,为什么我这个没有实现模拟点击
  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 保护模式-系统加载-段寄存器