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.

[参考译文] TM4C1294NCPDT:用于 Tiva 微控制器的简单 UDP 套接字编程

Guru**** 2479745 points
Other Parts Discussed in Thread: TM4C1294NCPDT

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/694609/tm4c1294ncpdt-simple-udp-socket-programming-for-the-tiva-microcontrollers

器件型号:TM4C1294NCPDT

尊敬的 TI 团队:

我有一个与 Tiva tm4c1294ncpdt 板的套接字编程相关的问题。

我正在尝试运行从互联网上获得的基于套接字的 UDP 编程的简单代码。

代码为:

/*
udpclient.c -简单的 UDP 客户端
*用法:udpclient 
*/
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define BUFSIZE 1024

//
*错误- perror 的包装器
*/
void 错误(char *msg){
镜(msg);
退出(0);
}

空 tcpHandler (UArg0、UArgarg1){
int sockfd、portno、n;
int serverlen;
struct sockaddr_in serveraddr;
struct hostent *server;
char *主机名;
字符 buf[BUFSIZE];

/*检查命令行参数*/
if (argc!= 3){
fprintf (stderr、"用法:%s \n"、argv[0]);
退出(0);
}
主机名= argv[1];
PORTNO = atoi (argv[2]);

/*套接字:创建套接字*/
sockkfd = socket (AF_iNet、SOCK_DGRAM、0);
if (sockkfd < 0)
错误("打开套接字时出错");

/* gethostbyname:获取服务器的 DNS 条目*/
服务器= gethostbyname (主机名);
if (server == NULL){
fprintf (stderr、"错误、没有像%s\n"这样的主机、主机名);
退出(0);
}

/*构建服务器的 Internet 地址*/
bzero ((char *)&serveraddr、sizeof (serveraddr));
serveraddr.sin 系列= AF_iNet;
bcopy ((char *) server->h_addr、
(char *)&serveraddr.sin addr.s_addr、server->h_length);
serveraddr.sin 端口= htons (portno);

/*从用户获取消息*/
bzero (buf、BUFSIZE);
printf ("请输入 msg:");
Fgets (buf、BUFSIZE、stdin);

/*将消息发送到服务器*/
serverlen = sizeof (serveraddr);
N = sendto (sendkff、buf、strlen (buf)、0、&serveraddr、 服务器 len);
如果(n < 0)
错误("sendto 中的错误");

/*打印服务器的回复*/
N = recvfrom (sockkfd、buf、strlen (buf)、0、&serveraddr、 服务器长度(&S);
如果(n < 0)
错误("recvfin"中的错误);
printf ("来自服务器的回显:%s"、buf);
返回0;
} 

我从以下网站获得:

www.cs.cmu.edu/.../udpclient.c 

现在、当我运行该代码时、我会遇到很多错误、这是与函数 gethostbyname 相关的所有函数中的第一个。 这说明它 没有定义、因此我想知道我如何在代码中访问此函数、因为 TI-NDK 支持 BSD 样式的网络套接字、所以我可以使用 gethostbyname 运行此代码。


现在、为了成功构建代码、我对代码进行了以下更改:

空 tcpHandler (UARg arg0、UARg arg1)
{
int sockfd、portno、n;
int serverlen;
struct sockaddr_in serveraddr;
struct hostent *server;
char *主机名;
字符 buf[BUFSIZE];

/*检查命令行参数*/
主机名="192.168.80.171";
PORTNO = 8888;

/*套接字:创建套接字*/
sockkfd = socket (AF_iNet、SOCK_DGRAM、0);
if (sockkfd < 0)
错误("打开套接字时出错");

/* gethostbyname:获取服务器的 DNS 条目*/
/*server = gethostbyname (hostname);
if (server == NULL){
fprintf (stderr、"错误、没有像%s\n"这样的主机、主机名);
EXIT (0);
}*/

/*构建服务器的 Internet 地址*/
bzero ((char *)&serveraddr、sizeof (serveraddr));
serveraddr.sin 系列= AF_iNet;
/*bcopy ((char *) server->h_addr、
(char *)&serveraddr.sin_addr.s_addr、server->h_length);*/
serveraddr.sin_addr.s_addr = inet_addr (主机名);
serveraddr.sin 端口= htons (portno);

/*从用户获取消息*/
bzero (buf、BUFSIZE);
printf ("请输入 msg:");
Fgets (buf、BUFSIZE、stdin);

/*将消息发送到服务器*/
serverlen = sizeof (serveraddr);
N = sendto (sendkff、buf、strlen (buf)、0、&serveraddr、 服务器 len);
如果(n < 0)
错误("sendto 中的错误");

/*打印服务器的回复*/
N = recvfrom (sockkfd、buf、strlen (buf)、0、&serveraddr、 服务器长度(&S);
如果(n < 0)
错误("recvfin"中的错误);
printf ("来自服务器的回显:%s"、buf);
返回0;
} 

但是、此代码崩溃显示了这一点:

启动
TCP 回显示例
系统提供商的闪存中的 SS 设置为 SysMin。 停止目标以查看 ROV 中的任何 SysMin 内容。
网络已添加:IF-1:192.168.80.154
OS.KNL.Task:第383行:E_spOutOfBounds:任务0x20000d08堆栈错误、SP = 0x3e8。
xdc.runtime.Error.raise:终止执行 

我使用了 tcpecho 代码、删除了 tcpHandler 函数中的所有内容、并将代码内容放在站点的主函数中、如代码中所示。

因此,请告诉我这一切的目的是什么,如果有人想模拟条件,而不是所有需要做的事情,就是用上述代码替换 tcpHandler 的内容,或者按原样复制上述代码。

请告诉我这些问题的产生原因,我在调试过程中知道的一件事是,尽管 NDK 支持 BSD 套接字,但我们仍然无法使用在 Linux 上运行的示例代码。

此致

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

    您好!

     如果您要使用 TI-RTOS NDK 堆栈、则已经有一个 udpEcho 示例可供您参考。

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

    乍一看、我假设调用 tcpHandler 的任务堆栈正在被烧断。 您通过命名 UDP 套接字函数 tcpHandler 来使这种情况变得混乱。

    char buf[1024]将在回显示例项目中使用整个#define TCPHANDLERSTACK 1024。 尝试增大此宏。

    要全面了解、您可以通过单击工具->运行时对象查看器->任务来确认问题。 然后将 Basic 选项更改为 Detailed、您应该会看到堆栈峰值大于堆栈大小。 NDK 有自己的堆栈、也可能会被吹出。

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

    你(们)好。

    现在、我进行了一个实验、那就是我从 TI 资源浏览器复制了 udpecho 代码并将其编译并成功运行。

    但这实际上是服务器代码,我想实施 UDP 客户端代码,因此请记住,我对 udpEcho.c 文件中的 echoFxn()进行了以下更改:

    void echoFxn (UArg arg0、UArg arg1)
    {
    内部 字节接收;
    内部 字节 Sent;
    内部 状态;
    内部 客户;
    FD_SET readSet;
    struct sockaddr_in ServerAddr;
    socklen_t 地址;
    特性 缓冲器[UDPPACKETSIZE];
    
    char* hostname ="192.168.80.171";
    int portno = 1000;
    
    客户端=套接字(AF_iNet、SOCK_DGRAM、IPPROTO_UDP);
    if (client ==-1){
    System_printf ("错误:未创建套接字。\n");
    转到关断;
    }
    
    memset (&ServerAddr、0、sizeof (struct sockaddr_in));
    ServerAddr.Sin_Family = AF_iNet;
    //ServerAddr.sin addr.s_addr = inet_addr (主机名);
    if (inet_aton (hostname、&ServerAddr.sin addr)==0){
    System_abort ("添加服务器 IP\n"时出错);
    }
    ServerAddr.Sin_port = htons (portno);
    
    for (;;){
    
    strcpy (buffer、"Hello Piyush");
    
    addrlen = sizeof (struct sockaddr_in);
    字节 Sent = sendto (client、buffer、strlen ("Hello Piyush")、0、
    (struct sockaddr *)&ServerAddr、addrlen);
    
    if (bytesSent < 0){
    System_printf ("错误:Sendto 失败。\n");
    转到关断;
    }
    
    //System_printf ("两个结构的大小:%d\t%d"、sizeof (struct sockadr)、sizeof (struct sockaddr_in));
    //System_flush();
    
    /*
    * readSet 和 addrlen 是值结果参数、必须重置
    *在每个 select()和 recvfrom ()调用之间
    */
    
    #if 1.
    fd_zero (readSet);
    FD_SET (客户端、readSet);
    addrlen = sizeof (ServerAddr);
    
    /*等待答复*/
    状态= select (client、readSet、NULL、NULL);
    如果(状态> 0){
    if (fd_isset (client、readSet)){
    bytesRcvd = recvfrom (客户端、缓冲区、UDPPACKETSIZE、0、
    (struct sockaddr *)&ServerAddr、&addrlen);
    
    如果(bytesRcvd >0){
    
    }
    }
    
    #endif
    
    Task_sleep(2000);
    
    }
    
    关断:
    if (client > 0){
    Close (client);
    }
    } 

    程序已成功构建并正在运行, 但问题是,我可以在 Wireshark 中看到从 UDP 客户端到 PC 的发送数据包,但在这里看不到接收数据包,Wireshark 中有一组黑色消息表示:

    33844 163.335566  192.168.80.154   192.168.80.171      ICMP        70         目标不可达(端口不可达)

     因此我知道我缺少一件小事,但我不想准确地找到这一点,所以我希望得到你们的帮助。

    此致

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

    PC 上的代码是什么样子的? 您需要将 bind ()绑定到客户端连接的同一端口。 通常、您不应尝试使用小于1024的端口。

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

    大家好、我将端口2050用于 UDP 通信。

    您能不能要求 TI 团队制作 UDPEcho 服务器代码的副本并将其修改为简单的 UDP 客户端代码。

    此致  

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

    我已经尝试了所有选项 connect、bind 等,但仍然无法通过 UDP 客户端代码进行通信。

    代码如下:

    void echoFxn (UArg arg0、UArg arg1)
    {
    内部 字节接收;
    内部 字节 Sent;
    内部 状态;
    内部 客户;
    FD_SET readSet;
    struct sockaddr_in ServerAddr;
    struct sockaddr_in clientAddr;
    结构时间值 超时;
    socklen_t 地址;
    特性 缓冲器[UDPPACKETSIZE];
    
    char* hostname ="192.168.80.171";
    //int portno = 2050;
    
    memset (&ServerAddr、0、sizeof (struct sockaddr_in));
    ServerAddr.Sin_Family = AF_iNet;
    ServerAddr.Sin_addr.s_addr = inet_addr (主机名);
    /*if (inet_aton (hostname、&ServerAddr.sin addr)==0){
    System_abort ("添加服务器 IP\n"时出错);
    }*/
    //ServerAddr.Sin_port = htons (portno);
    ServerAddr.Sin_port = htons (arg0);
    
    for (;;){
    
    客户端=套接字(ServerAddr.Sin_Family、SOCK_DGRAM、IPPROTO_UDP);
    if (client ==-1){
    System_printf ("错误:未创建套接字。\n");
    转到关断;
    }
    
    状态= 0;
    状态= connect (client、(struct sockadr *)&ServerAddr、sizeof (struct sockadr));
    if (status ==1)
    {
    System_printf ("错误:连接失败。\n");
    转到关断;
    }
    
    timeout.tv_sec = 10;
    timeout.tv_usec = 0;
    
    status = setsockopt (client、SOL_socket、SO_RCVTIMEO、&TIMEOUT、sizeof (struct timeval));
    if (status < 0){
    System_printf ("错误:超时失败。\n");
    转到关断;
    }
    
    strcpy (buffer、"Hello Piyush");
    
    addrlen = sizeof (struct sockaddr);
    字节 Sent = SEND (client、buffer、strlen ("Hello Piyush")、0);
    
    if (bytesSent < 0){
    System_printf ("错误:Sendto 失败。\n");
    转到关断;
    }
    
    fd_zero (readSet);
    FD_SET (客户端、readSet);
    addrlen = sizeof (ServerAddr);
    
    /*等待答复*/
    状态= SELECT (CLIENT、readSet、NULL、NULL、超时);
    如果(状态> 0){
    if (fd_isset (client、readSet)){
    字节接收= recv (客户端、缓冲区、UDPPACKETSIZE、0);
    
    if (bytesRcvd < 0){
    System_printf ("错误:恢复失败。\n");
    转到关断;
    }
    }
    
    
    Close (客户端);
    
    //Task_sleep (2000);
    }
    
    关断:
    if (client > 0){
    Close (client);
    }
    } 

    如果可能、请在您的末尾创建一个简单的 UDP 客户端、并在此处发布压缩文件。

    此致

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

    您好、Piyush、

    您可以尝试使用 updSendReceive"示例"作为基础、它应该具有您所需的内容。 可在以下位置找到该工具:
    /packages/examples/tools/udpSendReceive.c

    希望这有所帮助、
    Gerardo

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

    我已经检查过这个问题,看到我在这个论坛上几乎所有与我的问题有关的帖子,并尝试了所有这些帖子,尽管它们是部分解决方案,或者没有解决方案,但所有的努力都没有取得成果。

    您所讨论的源实际上是 PC 应用程序、它将在 Linux PC 上编译并在其上运行。

    此致

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

    您好、Piyush、

    由于这使用 BSD 套接字、因此可以稍微修改代码、以便能够在 NDK 上运行。

    您说它不起作用、但您没有详细介绍、您的一些电话是否返回错误?  

    BR、
    Gerardo

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

    您好、Piyush、

    这是否得到了解决? 我可以将其标记为"TI 认为已解决"吗?

    Todd

    [更新:我将此标记为"TI"认为已解决、并因原始海报中的静止状态而将其关闭。 如果您感觉不是这样、请发布回复、该主题将被打开。]