0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

基于MM32F3270以太网Server使用

jf_pJlTbmA9 来源:灵动MM32MCU 作者:灵动MM32MCU 2023-09-27 15:46 次阅读

前面重点对Client的创建方式及使用方式进行了介绍,本节通过Server实验对TCP通信过程进行一次介绍。

在TCP/IP协议中,传输层及以下层的机制是由内核提供的。应用层由用户提供,应用层程序对通信数据进行解析处理,传输层及以下层处理通信的细节(将数据从一端传入另外一端)。应用层数据通过协议栈发送到网络上时,每层协议都要增加一个数据部首(header),进行一次封装。其中不同的协议层对数据包有不同的称谓,在传输层叫段(segment),在网络层叫做数据报(datagram),在链路层称为帧(frame)。

poYBAGIB1SeAe163AAENFx_I-OI592.png
pYYBAGIB1SmAORngAAFqBTr68c8819.png

在通信过程中,发送端执行以下动作:首先程序进行编码,确定通信的建立连接、发送数据的时间。接着建立TCP连接,TCP根据应用指示负责建立连接、发送数据及断开连接。TCP首部包括源端口号和目标端口号、序号和校验和,加完首部后数据包继续往下传递到IP层,IP层加上IP首部包括地址等信息用于寻址操作,之后将数据继续往下传递附加数据链路层首部。最后发送时的分组数据包会加上以太网包尾(用于循环冗余校验)。

主机端:收到数据包后会在以太网数据包中找到MAC地址,判断是否为自己的数据包,如果不是则丢弃。如果是传递给IP层处理,以此类推,不断往上传递到TCP层。在TCP层通过校验和判断数据是否损坏,然后检查是否按序号接收数据,最后检查端口号。处理完成这一切后数据包继续往上层发送,即应用层。如果出现主机空间已满等情况,主机则会发送“处理异常”通知发送端。

poYBAGIB1SuAPknaAADy7PNlu3M323.png

实验使用MB-039开发板,在工程中使用LwIP+FreeRTOS,实验展示如何制作一个TCP Server,并收发数据,实验使用到的硬件如下:

poYBAGIB1SyAHYynAAG39uXw7q0489.png

如图是MB-039(完整原理图可以通过MM32官网下载)的ETH部分。

各个信号引脚对应如下:

pYYBAGIB1S6AEqaVAAAOapdym_Y980.png
poYBAGIB1TGAFwREAAi12qR49zc411.png

在进行Server实验前,我们先了解需要使用到的API

1)netconn_bind ()

2)netconn_listen ()

3)netconn_accept ()

以下分API展开介绍:

01、netconn_bind ()

从源码中可以看出其主要功能:为conn(服务器端)绑定地址与端口号。

err_t netconn_bind(struct netconn* conn, const ip_addr_t* addr, u16_t port)
{
    API_MSG_VAR_DECLARE(msg);
    err_t err;

    LWIP_ERROR("netconn_bind: invalid conn", (conn != NULL), return ERR_ARG;);
#if LWIP_IPV4
    /* Don't propagate NULL pointer (IP_ADDR_ANY alias) to subsequent functions */
    if (addr == NULL) {
        addr = IP4_ADDR_ANY;
    }
#endif /* LWIP_IPV4 */
#if LWIP_IPV4    LWIP_IPV6
    if ((netconn_get_ipv6only(conn) == 0)   
            ip_addr_cmp(addr, IP6_ADDR_ANY)) {
        addr = IP_ANY_TYPE;
    }
#endif /* LWIP_IPV4    LWIP_IPV6 */
    API_MSG_VAR_ALLOC(msg);
    API_MSG_VAR_REF(msg).conn = conn;
    API_MSG_VAR_REF(msg).msg.bc.ipaddr = API_MSG_VAR_REF(addr);
    API_MSG_VAR_REF(msg).msg.bc.port = port;
    err = netconn_apimsg(lwip_netconn_do_bind,  API_MSG_VAR_REF(msg));
    API_MSG_VAR_FREE(msg);
    return err;
}

02、netconn_listen ()

netconn_listen指向的函数是:netconn_listen_with_backlog,作用:使服务器进入监听状态,等待远端的连接请求。

err_t netconn_listen_with_backlog(struct netconn* conn, u8_t backlog)
{
#if LWIP_TCP
    API_MSG_VAR_DECLARE(msg);
    err_t err;

    /* This does no harm. If TCP_LISTEN_BACKLOG is off, backlog is unused. */
    LWIP_UNUSED_ARG(backlog);

    LWIP_ERROR("netconn_listen: invalid conn", (conn != NULL), return ERR_ARG;);

    API_MSG_VAR_ALLOC(msg);
    API_MSG_VAR_REF(msg).conn = conn;
#if TCP_LISTEN_BACKLOG
    API_MSG_VAR_REF(msg).msg.lb.backlog = backlog;
#endif /* TCP_LISTEN_BACKLOG */
    err = netconn_apimsg(lwip_netconn_do_listen,  API_MSG_VAR_REF(msg));
    API_MSG_VAR_FREE(msg);
    return err;
#else /* LWIP_TCP */
    LWIP_UNUSED_ARG(conn);
    LWIP_UNUSED_ARG(backlog);
    return ERR_ARG;
#endif /* LWIP_TCP */
}

03、netconn_accept ()

netconn_accept(代码较长,这里不进行粘贴)用于TCP服务器中,等待着远端主机的连接请求,并且建立一个新的TCP连接,在调用这个函数之前需要通过调用 listen()函数让服务器进入监听状态。accept()函数的调用会阻塞应用线程直至与远程主机建立TCP连接。参数addr是一个返回结果参数,它的值由accept()函数设置,其实就是远程主机的地址与端口号等信息,当新的连接已经建立后,远端主机的信息将保存在连接句柄中,能够标识连接对象。

了解了以上3个API,我们开始创建Server工程:

static void server(void* thread_param)
{
    struct netconn* conn, *newconn;
    err_t err;
    LWIP_UNUSED_ARG(arg);

#if LWIP_IPV6
    conn = netconn_new(NETCONN_TCP_IPV6);
    netconn_bind(conn, IP6_ADDR_ANY, LOCAL_PORT);         
#else /* LWIP_IPV6 */
    conn = netconn_new(NETCONN_TCP);               //①
    netconn_bind(conn, IP_ADDR_ANY, LOCAL_PORT);      //②
#endif /* LWIP_IPV6 */
    LWIP_ERROR("tcpecho: invalid conn", (conn != NULL), return;);

    printf("The local port number is%dnn", LOCAL_PORT);
    netconn_listen(conn);                              //③
    while (1) {
        err = netconn_accept(conn,  newconn);         //④
        if (err == ERR_OK) {
            struct netbuf* buf;
            void* data;
            u16_t len;

            while ((err = netconn_recv(newconn,  buf)) == ERR_OK) {    //⑤
                do {
                    netbuf_data(buf,  data,  len);
                    err = netconn_write(newconn, data, len, NETCONN_COPY);  //⑥
                } while (netbuf_next(buf) >= 0);
                netbuf_delete(buf);                 //⑦
            }
            netconn_close(newconn);         //⑧
            netconn_delete(newconn);        //⑨
        }
    }
}

1、申请一个连接结构,指定参数是NETCONN_TCP,即TCP连接

2、绑定本地的IP地址与端口号

3、使TCP服务器进入监听状态

4、处理客户端的连接请求,当只有当有客户端发送连接请求的时候才会处理,否则将进入阻塞态,而客户端的信息保存在newconn连接结构中

5、接收数据,并装填进buf

6、对接收的数据进行转发(指定为不拷贝方式NETCONN_COPY)

7、释放数据空间

8、主动关闭客户端的连接

9、释放newconn空间

到这里已经完成了工程的创建,看一下PC的IP地址,设备需要处于同一网段,以方便测试。

打开命令行窗口输入:ipconfig

pYYBAGIB1TOARaWcAAEnlBhO5H8936.png

PC的地址为:192.168.105.34,在sys_arch.h文件中对DEST_IP_ADDR0 、DEST_IP_ADDR1、DEST_IP_ADDR2、DEST_IP_ADDR3进行修改,DEST_PORT 随意修改。

#define LOCAL_PORT                 2021

#define IP_ADDR0                   192
#define IP_ADDR1                   168
#define IP_ADDR2                   105
#define IP_ADDR3                   21

将程序下载入开发板中,使用NetAssist进行如下设置:

1)协议设置,此时设备为Server,则PC为Client

2)设置远程主机地址(即设备地址)

3)端口号

poYBAGIB1TWAfwKHAAFh4dn4s7g430.png

点击连接,若提示连接失败,则Ping一下开发板地址,可以正常Ping通则检查端口号;如果无法Ping通则需要对工程进行检查。

pYYBAGIB1TeAM8KxAAFz6nHccxA983.png

任意输入字符进行发送。

pYYBAGIB1TmAADjoAAIx-OumLeg776.png

通过上图可以观察到发送成功,并且设备返回数据与发送数据一致,表明实验成功。实验程序请登录我们的官网下载MM32F3270 SDK,工程路径如下:~MM32F3270_Lib_Samples_V0.90Demo_appEthernet_DemoETH_RTOSFreertos_Server。

来源:灵动MM32MCU


审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 以太网
    +关注

    关注

    40

    文章

    5076

    浏览量

    166235
  • 通信
    +关注

    关注

    18

    文章

    5706

    浏览量

    134394
  • Server
    +关注

    关注

    0

    文章

    88

    浏览量

    23848
  • TCP
    TCP
    +关注

    关注

    8

    文章

    1271

    浏览量

    78291
收藏 人收藏

    评论

    相关推荐

    灵动微课堂 (第182讲) | 基于MM32F3270 以太网 Client_Socket使用

    :~\MM32F3270_Lib_Samples_V0.90\Demo_app\Ethernet_Demo\ETH_RTOS\Freertos_Client_socket下章的题目为《基于MM32F3270 以太网
    发表于 10-18 11:02

    灵动微课堂 (第183讲) | 基于MM32F3270 以太网 Server_Socket使用

    :~\MM32F3270_Lib_Samples_V0.90\Demo_app\Ethernet_Demo\ETH_RTOS\Freertos_Server_socket我们下节的题目为《基于MM32F3270
    发表于 10-18 11:08

    灵动微课堂 (第185讲) | 基于MM32F3270 以太网 Client使用

    前面介绍了基于Socket方式的以太网通讯,接下来给大家介绍基于TCP包的通讯。内容分为基于MM32F3270以太网Client的使用与基于MM32F3270
    发表于 10-18 11:21

    灵动微课堂 (第186讲) | 基于MM32F3270 以太网 Server使用

    :~\MM32F3270_Lib_Samples_V0.90\Demo_app\Ethernet_Demo\ETH_RTOS\Freertos_Server。我们下章的题目为《基于MM32F3270
    发表于 10-18 11:28

    灵动微课堂 (第187讲) | 基于MM32F3270 以太网 HTTP使用

    /mm32f_mainstream/mm32f3270/)下载MM32F3270 SDK,工程路径如下:~\MM32F3270_Lib_Samples_V0.90\Demo_app\E
    发表于 10-22 18:59

    MM32F3270系列32位MCU的特点有哪些

    上海灵动微电子推出全新主流型MM32F3270系列32位MCU,此款MM32F3270系列是基于M3内核的32位微控制器,MM32F3270适用于要求高集成度的高性能控制领域,如:工业控制、消防监控
    发表于 11-03 07:20

    灵动微电子MM32F3270系列MCU的特点介绍

    上海灵动微电子推出全新主流型MM32F3270系列32位MCU,此款MM32F3270系列是基于M3内核的32位微控制器,MM32F3270适用于要求高集成度的高性能控制领域,如:工业控制、消防监控
    发表于 03-22 16:57 1945次阅读

    基于MM32F3270 以太网 Server使用

    前面重点对Client的创建方式及使用方式进行了介绍,本节通过Server实验对TCP通信过程进行一次介绍。
    发表于 02-08 13:36 0次下载
    基于<b class='flag-5'>MM32F3270</b> <b class='flag-5'>以太网</b> <b class='flag-5'>Server</b>使用

    基于MM32F3270 以太网 Client使用

    接下来给大家介绍基于TCP包的通讯。内容分为基于MM32F3270以太网Client的使用与基于MM32F3270以太网Server的使用。
    发表于 02-08 15:10 0次下载
    基于<b class='flag-5'>MM32F3270</b> <b class='flag-5'>以太网</b> Client使用

    基于MM32F3270 I2S使用

    基于MM32F3270 I2S使用
    的头像 发表于 09-27 15:50 502次阅读
    基于<b class='flag-5'>MM32F3270</b> I2S使用

    基于MM32F3270以太网HTTP使用

    基于MM32F3270以太网HTTP使用
    的头像 发表于 09-27 15:48 331次阅读
    基于<b class='flag-5'>MM32F3270</b><b class='flag-5'>以太网</b>HTTP使用

    基于MM32F3270以太网Client使用

    基于MM32F3270以太网Client使用
    的头像 发表于 09-27 15:44 439次阅读
    基于<b class='flag-5'>MM32F3270</b><b class='flag-5'>以太网</b>Client使用

    基于MM32F3270以太网UDP使用

    基于MM32F3270以太网 UDP使用
    的头像 发表于 09-27 15:42 283次阅读
    基于<b class='flag-5'>MM32F3270</b><b class='flag-5'>以太网</b>UDP使用

    基于MM32F3270以太网Server_Socket使用

    基于MM32F3270以太网Server_Socket使用
    的头像 发表于 09-27 15:41 263次阅读
    基于<b class='flag-5'>MM32F3270</b><b class='flag-5'>以太网</b><b class='flag-5'>Server</b>_Socket使用

    基于MM32F3270以太网Client_Socket使用

    基于MM32F3270以太网Client_Socket使用
    的头像 发表于 09-27 15:37 354次阅读
    基于<b class='flag-5'>MM32F3270</b><b class='flag-5'>以太网</b>Client_Socket使用