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.

[参考译文] MSP432E401Y:Simplelink TCP 客户端示例的贡献帖子/指南

Guru**** 2394305 points
Other Parts Discussed in Thread: MSP432E401Y

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1043302/msp432e401y-contribution-post-guide-for-simplelink-tcp-client-example

器件型号:MSP432E401Y

尊敬的 TI 社区:

我只是想回馈我、因为我在这里有好的人帮助我。 有很多关于 TCP 客户端以及如何使其正常工作的文章、但我认为这些都在我看来。 希望这篇文章总结了人们在未来需要做的事情、就 Simplelink NDK API 而言。

对于 TCP 客户端示例、虽然可以修改用于 TCP Server 的 SDK 中的现有 Python 脚本以使其正常工作、但以下步骤旨在减少工作量。 下面提供的代码会发送消息以及从服务器接收消息。 它将一直阻止、直到发送服务器消息。

谢谢、

乌特 sav

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

    器件型号:MSP432E401Y



    1.从 https://www.hw-group.com/software/hercules-setup-utility 下载并安装 Hercules 工具 。 此工具允许计算机成为 TCP 服务器/客户端等。 无需代码!

    2.单击 TCP Server (TCP 服务器)选项卡,在 Port (端口)字段下输入端口号。 除非您知道自己在做什么、否则将茶授权设为默认值。


    3.在 Simplelink tcpEcho 示例中将 tcpEcho.c 和 tcpEchoHooks.c 替换为以下代码。 根据您的需求进行修改。 单击 Server Echo (服务器回显)复选框以在键入消息以发送到客户端时查看消息。
       

    注意:在示例中、tcpEcho.c 的代码具有 IP 地址。 将其替换为网络服务启动时打印的动态 IP 或放入通过.syscfg 分配的静态 IP。 我可以在另一篇文章中介绍如何设置请求时的静态 IP。

    tcpEchoHooks.c:

    /*
     * Copyright (c) 2015-2019, Texas Instruments Incorporated
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * *  Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     * *  Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the distribution.
     *
     * *  Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     */
    
    /*
     *    ======== tcpEchoHooks.c ========
     */
    
    #include <stdlib.h>
    #include <stdint.h>
    #include <stdbool.h>
    
    #include <pthread.h>
    
    
    /* XDC module Header Files */
    #include <xdc/std.h>                                                            // XDC "base types" - must be included FIRST
    #include <xdc/runtime/Types.h>                                                  // XDC constants/types used in xdc.runtime pkg
    #include <xdc/cfg/global.h>                                                     // For all BIOS instances created statically in RTOS .cfg file
    #include <xdc/runtime/Error.h>                                                  // For error handling (e.g. Error block)
    #include <xdc/runtime/System.h>
    
    /* TI-RTOS Kernel Header Files */
    #include <ti/sysbios/BIOS.h>
    #include <ti/sysbios/knl/Task.h>
    
    #include <ti/ndk/inc/netmain.h>
    
    #include <ti/ndk/slnetif/slnetifndk.h>
    #include <ti/net/slnet.h>
    #include <ti/net/slnetif.h>
    #include <ti/net/slnetutils.h>
    
    #include <ti/display/Display.h>
    #include <ti/drivers/emac/EMACMSP432E4.h>
    
    #define TCPPORT 65
    #define TCPHANDLERSTACK 2048
    
    /* Prototypes */
    //extern void *tcpHandler(void *arg0);
    extern void tcpClient(UArg a0, UArg a1);
    extern void *tcpClientThread(void *arg0);
    
    extern Display_Handle display;
    
    /*
     *  ======== netIPAddrHook ========
     *  user defined network IP address hook
     */
    void netIPAddrHook(uint32_t IPAddr, unsigned int IfIdx, unsigned int fAdd)
    {
        pthread_t           thread;
        pthread_attr_t      attrs;
        struct sched_param  priParam;
        int                 retc;
        int                 detachState;
        uint32_t            hostByteAddr;
        static uint16_t     arg0 = TCPPORT;
        static bool         createTask = true;
        int32_t             status = 0;
    
        if (fAdd) {
            Display_printf(display, 0, 0, "Network Added: ");
        }
        else {
            Display_printf(display, 0, 0, "Network Removed: ");
        }
    
        /* print the IP address that was added/removed */
        hostByteAddr = NDK_ntohl(IPAddr);
        Display_printf(display, 0, 0, "If-%d:%d.%d.%d.%d\n", IfIdx,
                (uint8_t)(hostByteAddr>>24)&0xFF, (uint8_t)(hostByteAddr>>16)&0xFF,
                (uint8_t)(hostByteAddr>>8)&0xFF, (uint8_t)hostByteAddr&0xFF);
    
        /* initialize SlNet interface(s) */
        status = ti_net_SlNet_initConfig();
        if (status < 0)
        {
            Display_printf(display, 0, 0, "Failed to initialize SlNet interface(s)"
                           "- status (%d)\n", status);
            while (1);
        }
    
    
        if (fAdd && createTask) {
            /*
             *  Create the Task that farms out incoming TCP connections.
             *  arg0 will be the port that this task listens to.
             *  @note - Only pthread works. Not sure why
             */
    
            /* Set priority and stack size attributes */
            pthread_attr_init(&attrs);
            priParam.sched_priority = 1;
    
            detachState = PTHREAD_CREATE_DETACHED;
            retc = pthread_attr_setdetachstate(&attrs, detachState);
            if (retc != 0) {
                Display_printf(display, 0, 0,
                        "netIPAddrHook: pthread_attr_setdetachstate() failed\n");
                while (1);
            }
    
            pthread_attr_setschedparam(&attrs, &priParam);
    
            retc |= pthread_attr_setstacksize(&attrs, TCPHANDLERSTACK);
            if (retc != 0) {
                Display_printf(display, 0, 0,
                        "netIPAddrHook: pthread_attr_setstacksize() failed\n");
                while (1);
            }
    
            retc = pthread_create(&thread, &attrs, tcpClientThread, (void *)&arg0);
            if (retc != 0) {
                Display_printf(display, 0, 0,
                        "netIPAddrHook: pthread_create() failed\n");
                while (1);
            }
    
            createTask = false;
    
        }
    }
    
    /*
     *  ======== serviceReport ========
     *  NDK service report.  Initially, just reports common system issues.
     */
    void serviceReport(uint32_t item, uint32_t status, uint32_t report, void *h)
    {
        static char *taskName[] = {"Telnet", "", "NAT", "DHCPS", "DHCPC", "DNS"};
        static char *reportStr[] = {"", "Running", "Updated", "Complete", "Fault"};
        static char *statusStr[] =
            {"Disabled", "Waiting", "IPTerm", "Failed","Enabled"};
    
        Display_printf(display, 0, 0, "Service Status: %-9s: %-9s: %-9s: %03d\n",
                taskName[item - 1], statusStr[status], reportStr[report / 256],
                report & 0xFF);
    
        /* report common system issues */
        if ((item == CFGITEM_SERVICE_DHCPCLIENT) &&
                (status == CIS_SRV_STATUS_ENABLED) &&
                (report & NETTOOLS_STAT_FAULT)) {
            Display_printf(display, 0, 0,
                    "DHCP Client initialization failed; check your network.\n");
    
            while (1);
        }
    }



    tcpEcho.c:

    /*
     * Copyright (c) 2014-2019, Texas Instruments Incorporated
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * *  Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     * *  Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the distribution.
     *
     * *  Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     */
    
    /*
     *    ======== tcpEcho.c ========
     *    Contains BSD sockets code.
     */
    
    /* For usleep() */
    #include <unistd.h>
    #include <stdint.h>
    #include <stddef.h>
    #include <string.h>
    #include <stdio.h>
    
    #include <pthread.h>
    
    
    /* NDK support */
    #include <ti/ndk/inc/socketndk.h>
    #include <ti/ndk/inc/socket.h>
    #include <ti/ndk/inc/netmain.h>
    
    #include <ti/net/slnetutils.h>
    
    
    #include <ti/display/Display.h>
    
    #define TCPPACKETSIZE 256
    
    extern Display_Handle display;
    
    extern int fdOpenSession(void *hTask);
    extern void fdCloseSession(void *hTask);
    extern void *TaskSelf();
    
    
    /*
     *  ======== tcpWorker ========
     *  Task to handle TCP connection. Can be multiple Tasks running
     *  this function.
     */
    
    void *tcpClientThread(void *arg0){
        fdOpenSession(TaskSelf());
    
        struct sockaddr_in serverAddr;
        uint16_t port = *((uint16_t *)(arg0));
    
        Display_printf(display, 0, 0, "TCP Echo example started\n");
    
        SOCKET clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    
        if(clientSocket == INVALID_SOCKET){
            Display_printf(display, 0, 0, "Con, err: [%d]\n", fdError());
            Display_printf(display, 0, 0, "Unable to create socket\n");
        }
    
        /* SL supports IPv4 DNS only */
        bzero(&serverAddr, sizeof(struct sockaddr_in));
        serverAddr.sin_family = AF_INET;
        serverAddr.sin_port = NDK_htons(port); // Pass to arg0 or hard code here
        /* Replace with Dynamic Ip printed in example 
        *  or static ip set in .syscfg
        */
        serverAddr.sin_addr.s_addr = inet_addr("192.168.86.217"); 
    
    /* @note Uncomment for optional Socket options
     *
     * {
            struct timeval timeout;
            // Configure our Tx and Rx timeout to be 5 seconds
            timeout.tv_sec = 5;
            timeout.tv_usec = 0;
            int res = NDK_setsockopt(clientSocket, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof( timeout ) );
    
            if(res < 0){
                Display_printf(display, 0, 0, "Con, err: [%d]\n", fdError());
                Display_printf(display, 0, 0, "Unable to setSocketopt\n");
            }
        }
            // Linger ensures that
        {
            struct linger lng;
            lng.l_onoff = 1; // enable linger
            lng.l_linger = 1; // seconds
            int res = NDK_setsockopt(clientSocket, SOL_SOCKET, SO_LINGER, &lng,
                  sizeof(lng));
    
            if(res < 0){
                Display_printf(display, 0, 0, "Con, err: [%d]\n", fdError());
                Display_printf(display, 0, 0, "Unable to setSocketopt\n");
            }
        }
        {
            // Set KEEPALIVE option to 1
            int                optval;
            int                optlen = sizeof(optval);
            optval = 1;
            int res = NDK_setsockopt(clientSocket, SOL_SOCKET, SO_KEEPALIVE, &optval, optlen);
    
            if(res < 0){
                Display_printf(display, 0, 0, "Con, err: [%d]\n", fdError());
                Display_printf(display, 0, 0, "Unable to setSocketopt\n");
            }
        }*/
    
        int connectStatus;
        connectStatus = connect(clientSocket, (struct sockaddr *)&serverAddr, sizeof(serverAddr));
    
        if(connectStatus < 0){
            Display_printf(display, 0, 0, "Con, err: [%d]\n", fdError());
            Display_printf(display, 0, 0, "Unable to connect socket\n");
            sleep(2);
        }else{
            Display_printf(display, 0, 0, "Connected\n");
        }
    
        char *sendBuffer = "I am the Client. Hello :)\n";
        int nbytes = strlen(sendBuffer) + 1;
        send(clientSocket, (char *)sendBuffer, nbytes, 0 );
    
        char recvBuffer[TCPPACKETSIZE] = {0}; //Either this or heap allocated space
    
        while(1){
    
            Display_printf(display, 0, 0, "\nSend a message from server!\n");
            int bytes = recv(clientSocket, (char *)recvBuffer, 1000, 0);
            if (bytes > 0) {
                Display_printf(display, 0, 0, "\n%s\n", recvBuffer);
            }else if (bytes == 0){
                Display_printf(display, 0, 0, "\nServer shutdown\n");
            }else{
                Display_printf(display, 0, 0, "\nFailed to get bytes\n");
            }
        }
    
    shutdown:
    
        if(shutdown(clientSocket,
                        SHUT_RD) < 0){
            Display_printf(display, 0, 0, "Con, err: [%d]\n", fdError());
            Display_printf(display, 0, 0, "Unable to shutdown socket\n");
        }
        fdCloseSession(TaskSelf());
        return(NULL);
    }