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:错误套接字未阻塞?

Guru**** 2538930 points


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

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

器件型号:F28M36P63C2

工具/软件:TI-RTOS

我一直在尝试调试 TCP 套接字出现的问题、似乎它们没有被阻止。

为了将问题固定下来、我重新安装了 TI-RTOS 2.16.1.14并导入了 tcpEcho 演示、并进行了极少的修改以重现问题。

请注意、实际的演示程序在无限循环中运行、返回0字节、占用可用的 CPU 周期、直到数据在套接字上。  BSD 套接字(它正在使用它)应阻止、直到套接字上有数据、发生超时或错误(设置了 errno)。  为了重现问题,我修改了 tcpWorker()子例程,如下所示:

空 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);

即使我指定 MSG_WAITALL (我也尝试不使用),recv()也会继续返回0个字节,但未设置错误。

我以前曾尝试报告过问题、但没有得到任何有用的回答、因此我再次尝试。

谢谢、

-Gary Brack

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

    您好、Gary、

     

    抱歉、我掉了另一个线程。 我以为我在我的漫长周末之前已经把它交给了。 我刚刚运行了 TCP Echo 示例、无法重现您的问题。 我使用的是 TM4C 而不是 Concerto 电路板...需要找到一个来尝试它。

     

    下面是我执行的步骤

    1.构建/运行开箱即用 TCP 回波

    2.请参阅 CCS 控制台中的目标 IP 地址

    3.从我的笔记本电脑运行 tcpSendReceive.exe (>tcpSendReceive.exe 146.252.162.119 1000 0)。 让它打印几次以查看它是否正常工作

    4.同时运行 Wireshark 以确认数据包来回传输。

    5. Ctrl-S The tcpSendReceive.exe

    6.停止目标并查看 ROV->Task->Call Stack 以确认 tcpWorker 是否处于 recv 中。

    7.在接收后将断点放在 tcpWorker 中。

    8.恢复目标并确认未命中断点。

    9. Ctrl-Q tcpSendReceive.exe 并确认已在目标上命中断点。

     

    我使用您的代码片段重复上述步骤、并得到相同的结果。 我所做的唯一更改是删除 System_flush、因为这使得测试更容易运行。

     

    Todd

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

    Todd、

    我不熟悉 TM4C 板、因此我无法评论它与 Concerto 之间的任何差异、甚至无法评论 tcpEcho 演示之间的差异。  

    从测试的声音可以看到,您没有对 tcpWorker()子例程进行任何修改。  假设没有更改,演示代码与 tcpWorker()例程相同:

    空 tcpWorker (UARg arg0、UARg arg1)
    {
    int clientfd =(int) arg0;
    int bytesRcvd;
    int bytesSent;
    char buffer[TCPPACKETSIZE];
    
    System_printf ("tcpWorker:start clientfd = 0x%x\n"、clientfd);
    system_flush();
    
    while ((bytesRcvd = recv (clientfd、buffer、TCPPACKETSIZE、0))> 0){
    字节 Sent = SEND (clientfd、buffer、字节 Rcvd、0);
    if (bytesSent < 0 || bytesSent!= bytesRcvd){
    System_printf ("错误:发送失败。\n");
    中断;
    }
    }
    system_printf ("tcpWorker stop clientfd = 0x%x\n"、clientfd);
    
    close (clientfd);
    } 

    我不清楚如何在 while 循环表达式中的 recv()之后插入断点。  我观察到的是,recv()调用持续返回0,导致>0测试失败,并再次调用 Receive,直到最终收到消息。  这就是为什么在我修改的版本中,我移动了 while 循环内的 recv(),并将其更改为 while (true)无限循环。  为了确认返回0、我添加了打印 recvBytes 和 errno 来演示返回0字节(只有在出现错误(超时、套接字关闭等)时才会发生这种情况。  

    在产生错误并且不相信它之后,我继续并单步执行 recv()调用(通过 TI-RTOS/NDK 子例程调用) 在 recv 缓冲区中找不到它能够执行 semTEK()的信标,并让操作系统阻止它,以便 NDK 任务可以在它接收套接字上的数据时执行 semGive()。  (但 TM4C 板可能有所不同)

    我在测试中注意到的另一个差异是、您运行了测试客户端并让其首先发送数据。  我只是为了让它执行 connect()来创建 tcpWorker()任务,但从未发送任何数据。  我不认为这很重要、我只是想我应该提到它。

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

    您好、Gary、

    我找到了 Concerto 板。 我尝试复制您的设置。 我的笔记本电脑上有一个只连接到端口1000的工具。 我在上面代码的第8、12和18行有一个断点。 连接后、我按预期按断点8、因此我继续。 我等待一段时间(~40秒)、并且我从未遇到另一个断点。 断开工具连接后、我单击 Concerto 板上的断点18 (如预期的那样)。

    当我查看 Wireshark 时、我会看到以下内容 (注释146.252.163.100是 Concerto 板)

    套接字上未传输任何其他数据。 您在 Wireshark 上看到了什么? 当连接断开时、我只会得到0字节的字节接收。

    Todd

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

    Todd、

    我在7月31日之前休假。  当我返回时、我会把它拾取。

    -Gary

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    听起来不错。 感谢您的告知。 很棒的休息!

    Todd