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

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

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

1个回答

我的具体代码如下:
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);
}

}

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问
相关内容推荐