This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] RTOS/F28M36P63C2:TI-RTOS 套接字不阻塞??

Guru**** 2539500 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/607166/rtos-f28m36p63c2-ti-rtos-sockets-not-blocking

器件型号:F28M36P63C2

工具/软件:TI-RTOS

我一直在尝试调试一个问题、似乎 TCP 套接字没有被阻止。  为了获得帮助、我从 tcpEcho 演示中重新创建了症状、并进行了最少的修改。

我首先使用随 TI-RTOS 分发的基本 tcpEcho 演示程序。  实际的演示程序以无限循环方式运行、返回0字节、占用可用的 CPU 周期、直到数据在套接字上。  BSD 套接字(它正在使用它)应阻止、直到套接字上有数据、发生超时或错误(设置了 errno)。

要尝试解决此问题,我修改了 tcpWorker()子例程,以明确使用 MSG_WAITALL,如下所示:

空 tcpWorker (UARg arg0、UARg arg1) {
  int clientfd =(int) arg0;
  int bytesRcvd;
  int bytesSent;
  char buffer[TCPPACKETSIZE];
  int notdone = true;

  System_printf ("tcpWorker:start clientfd = 0x%x\n"、clientfd);

  while (notdone){
    //应阻止直到 TCPPACKETSIZE 字节被接收或错误。
    bytesRcvd = recv (clientfd、buffer、TCPPACKETSIZE、MSG_WAITALL);
    System_printf ("已接收%d 个字节。 errno =%d.\n"、bytesRcvd、errno);
    System_flush ();

    字节 Sent = SEND (clientfd、buffer、字节 Rcvd、0);
    if (bytesSent < 0 || bytesSent!= bytesRcvd){
       System_printf ("错误:发送失败。\n");
       中断;
    }
   }
  system_printf ("tcpWorker stop clientfd = 0x%x\n"、clientfd);
  system_flush();

   close (clientfd);

在这样做之后,请注意 recv()将继续返回0字节,而不会出现错误。

我继续使用标准 select()循环实现对其进行测试(正如我的实际应用使用的那样):

/*
*==== tcpWorker2 ====
*为标准 select()循环修改了 tcpWorker 示例。
*
空 tcpWorker2 (UARg arg0、UARg arg1){
  int clientfd =(int) arg0;
  int bytesRcvd;
  int bytesSent;
  char buffer[TCPPACKETSIZE];
  int notdone = true;

  System_printf ("tcpWorker:start clientfd = 0x%x\n"、clientfd);

  while (notdone){
    FD_SET READ_FDS;
    内部 NFD;

    fd_zero (read_fds);
    fd_set (clientfd、read_fds);

    //超时 NULL 应该永远阻止,但不会阻止
    NFD = SELECT (FD_SETSIZE、&READ_FDS、(FD_SET*) 0、(FD_SET *) 0、(struct timeval *) NULL);

    if (NFD <0){
       system_printf ("tcpWorker2:select()错误。 errno =%d\n"、errno);
       中断;
    }
    否则、如果(NFD = 0){
       //选择超时不为 NULL 且没有可用数据时发生
       System_printf ("tcpWorker2:select() timeout.\n");
       继续;
     }
     否则{
       system_printf ("tcpWorker2:select()返回%d\n"、NFD);
     }

    if (fd_isset (clientfd、&read_FDS)){
       bytesRcvd = recv (clientfd、buffer、TCPPACKETSIZE、0);
       System_printf ("tcpWorker2:接收到%d 个字节。 errno =%d.\n"、bytesRcvd、errno);
       system_flush();

       字节 Sent = SEND (clientfd、buffer、字节 Rcvd、0);
       if (bytesSent < 0 || bytesSent!= bytesRcvd){
           System_printf ("错误:发送失败。\n");
           中断;
        }
     }
  }
  system_printf ("tcpWorker stop clientfd = 0x%x\n"、clientfd);
  system_flush();

  close (clientfd);

在 tcpWorker2()示例中,无论端口上是否有数据,select()都将持续返回 NFD 为1,并且永远不会阻止 select()调用无效。  

我甚至显式测试了将块的超时设置为5秒(在第3版中)而不是 NULL。

是否有人可以向我指出 select()循环实际阻塞的实际演示?

谢谢、

-Gary