99精品伊人亚洲|最近国产中文炮友|九草在线视频支援|AV网站大全最新|美女黄片免费观看|国产精品资源视频|精彩无码视频一区|91大神在线后入|伊人终合在线播放|久草综合久久中文

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

基于MM32F3270以太網(wǎng)Client使用

jf_pJlTbmA9 ? 來源:靈動(dòng)MM32MCU ? 作者:靈動(dòng)MM32MCU ? 2023-09-27 15:44 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

前面介紹了基于Socket方式的以太網(wǎng)通訊,接下來給大家介紹基于TCP包的通訊。內(nèi)容分為基于MM32F3270以太網(wǎng)Client的使用與基于MM32F3270以太網(wǎng)Server的使用。

首先,對(duì)TCP有個(gè)簡(jiǎn)單的介紹:

TCP是一種面向連接的、可靠的、基于字節(jié)流的傳輸層通信協(xié)議。即客戶端和服務(wù)器之間在交換數(shù)據(jù)之前會(huì)先建立一個(gè)TCP連接,才能相互傳輸數(shù)據(jù)。并且提供超時(shí)重發(fā),丟棄重復(fù)數(shù)據(jù),檢驗(yàn)數(shù)據(jù),流量控制等功能,保證數(shù)據(jù)能從一端傳到另一端。

TCP優(yōu)點(diǎn):可靠、穩(wěn)定,TCP的可靠體現(xiàn)在TCP在傳遞數(shù)據(jù)之前,會(huì)有三次握手來建立連接,而且在數(shù)據(jù)傳遞時(shí),有確認(rèn)、窗口、重傳、擁塞控制機(jī)制,在數(shù)據(jù)傳完后,還會(huì)斷開連接用來節(jié)約系統(tǒng)資源。

TCP的缺點(diǎn):慢,效率低,占用系統(tǒng)資源高,易被攻擊,TCP在傳遞數(shù)據(jù)之前,要先建連接,這會(huì)消耗時(shí)間,而且在數(shù)據(jù)傳遞時(shí),確認(rèn)機(jī)制、重傳機(jī)制、擁塞控制機(jī)制等都會(huì)消耗大量的時(shí)間,而且要在每臺(tái)設(shè)備上維護(hù)所有的傳輸連接,事實(shí)上,每個(gè)連接都會(huì)占用系統(tǒng)的CPU、內(nèi)存等硬件資源。由于TCP存在確認(rèn)機(jī)制和三次握手機(jī)制,這些是導(dǎo)致TCP容易被人利用,實(shí)現(xiàn)DOS、DDOS、CC等攻擊。

接下來,介紹Client 的使用實(shí)現(xiàn):

Demo使用MB-039開發(fā)板,在工程中使用LwIP+FreeRTOS,實(shí)驗(yàn)展示如何制作一個(gè)Client端,并發(fā)送數(shù)據(jù),實(shí)驗(yàn)使用到的硬件如下:

poYBAGIB1SyAHYynAAG39uXw7q0489.png

如圖是MB-039(完整原理圖可以通過MM32官網(wǎng)下載)的ETH部分。

各個(gè)信號(hào)引腳對(duì)應(yīng)如下:

pYYBAGIB1S6AEqaVAAAOapdym_Y980.png
poYBAGIB1TGAFwREAAi12qR49zc411.png

在進(jìn)行Client實(shí)驗(yàn)前,我們先了解需要使用到的API

1)netconn_new ()

2)netconn_connect ()

3)netconn_write ()

每一個(gè)函數(shù)實(shí)現(xiàn)的功能:

01、netconn_new ()

netconn_new的功能為創(chuàng)建一個(gè)新的連接結(jié)構(gòu),結(jié)構(gòu)類型可以為TCP/UDP其源碼如下:

struct netconn*
netconn_new_with_proto_and_callback(enum netconn_type t, u8_t proto, netconn_callback callback)
{
    struct netconn* conn;
    API_MSG_VAR_DECLARE(msg);
    API_MSG_VAR_ALLOC_RETURN_NULL(msg);

    conn = netconn_alloc(t, callback);
    if (conn != NULL) {
        err_t err;

        API_MSG_VAR_REF(msg).msg.n.proto = proto;
        API_MSG_VAR_REF(msg).conn = conn;
        err = netconn_apimsg(lwip_netconn_do_newconn,  API_MSG_VAR_REF(msg));
        if (err != ERR_OK) {
            LWIP_ASSERT("freeing conn without freeing pcb", conn->pcb.tcp == NULL);
            LWIP_ASSERT("conn has no recvmbox", sys_mbox_valid( conn->recvmbox));
#if LWIP_TCP
            LWIP_ASSERT("conn->acceptmbox shouldn't exist", !sys_mbox_valid( conn->acceptmbox));
#endif /* LWIP_TCP */
#if !LWIP_NETCONN_SEM_PER_THREAD
            LWIP_ASSERT("conn has no op_completed", sys_sem_valid( conn->op_completed));
            sys_sem_free( conn->op_completed);
#endif /* !LWIP_NETCONN_SEM_PER_THREAD */
            sys_mbox_free( conn->recvmbox);
            memp_free(MEMP_NETCONN, conn);
            API_MSG_VAR_FREE(msg);
            return NULL;
        }
    }
    API_MSG_VAR_FREE(msg);
    return conn;
}

從源碼中可以看出,其功能為申請(qǐng)并初始化一個(gè)netconn結(jié)構(gòu)體,同時(shí)在netconn_alloc函數(shù)中為conn變量創(chuàng)建一個(gè)接收郵箱(recvmbox),和一個(gè)信號(hào)量(conn->op_completed)。內(nèi)存申請(qǐng)成功后使用netconn_apimsg函數(shù)構(gòu)建一個(gè)消息,使用OS的系統(tǒng)郵箱發(fā)送給內(nèi)核,請(qǐng)求以太網(wǎng)協(xié)議棧去執(zhí)行l(wèi)wip_netconn_do_newconn()函數(shù),在執(zhí)行時(shí)使用conn->op_completed進(jìn)行信號(hào)量同步,任務(wù)處理完成后,釋放一個(gè)信號(hào)量表示任務(wù)完成。

02、netconn_connect ()

netconn_connect作用為建立連接,在調(diào)用時(shí)將服務(wù)器端IP地址、端口號(hào)和本地的netconn結(jié)構(gòu)綁定,源碼如下:

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

    LWIP_ERROR("netconn_connect: 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 */

    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_connect,  API_MSG_VAR_REF(msg));
    API_MSG_VAR_FREE(msg);

    return err;
}

從源碼中可以看出,其功能為使用netconn_apimsg創(chuàng)建一個(gè)消息,通過執(zhí)行l(wèi)wip_netconn_do_connect進(jìn)行信號(hào)量的同步,將addr、port與conn進(jìn)行綁定。

03、netconn_write ()

netconn_write()為處于穩(wěn)定狀態(tài)的TCP協(xié)議發(fā)送數(shù)據(jù)。TCP協(xié)議數(shù)據(jù)以數(shù)據(jù)流的方式傳遞,因此只需要知道地址、長(zhǎng)度及需要發(fā)送的數(shù)據(jù)即可,其實(shí)際函數(shù)為netconn_write_vectors_partly(源碼較長(zhǎng),就不貼出來了)。重點(diǎn)關(guān)注一下官方API文檔對(duì)于apiflags參數(shù)的介紹:

* @param apiflags combination of following flags :
* - NETCONN_COPY: data will be copied into memory belonging to the stack
* - NETCONN_MORE: for TCP connection, PSH flag will be set on last segment sent
* - NETCONN_DONTBLOCK: only write the data if all data can be written at once

apiflags的值為NETCONN_COPY時(shí),dataptr指針指向的數(shù)據(jù)將會(huì)被拷貝到為這些數(shù)據(jù)分配的內(nèi)部緩沖區(qū),在調(diào)用本函數(shù)之后可以直接對(duì)這些數(shù)據(jù)進(jìn)行修改而不會(huì)影響數(shù)據(jù),但是拷貝的過程是需要消耗系統(tǒng)資源的,CPU需要參與數(shù)據(jù)的拷貝,而且還會(huì)占用新的內(nèi)存空間。

apiflags值為NETCONN_NOCOPY時(shí),數(shù)據(jù)不會(huì)被拷貝而是直接使用dataptr指針來引用。但是這些數(shù)據(jù)在函數(shù)調(diào)用后不能立即被修改,因?yàn)檫@些數(shù)據(jù)可能會(huì)被放在當(dāng)前TCP連接的重傳隊(duì)列中,以防對(duì)方未收到數(shù)據(jù)進(jìn)行重傳,而這段時(shí)間是不確定的。但是如果用戶需要發(fā)送的數(shù)據(jù)在ROM中(靜態(tài)數(shù)據(jù)),這樣子就無需拷貝數(shù)據(jù),直接引用數(shù)據(jù)即可。

apiflags值為NETCONN_MORE時(shí),那么接收端在組裝這些TCP報(bào)文段的時(shí)候,會(huì)將報(bào)文段首部的PSH標(biāo)志置一,這些數(shù)據(jù)完成組裝的時(shí)候,將會(huì)被立即遞交給上層應(yīng)用。

apiflags值為NETCONN_DONTBLOCK時(shí),表示在內(nèi)核發(fā)送緩沖區(qū)滿的時(shí)候,再調(diào)用netconn_write()函數(shù)將不會(huì)被阻塞,而是會(huì)直接返回一個(gè)錯(cuò)誤代碼ERR_VAL告訴應(yīng)用程序發(fā)送數(shù)據(jù)失敗,應(yīng)用程序可以自行處理這些數(shù)據(jù),在適當(dāng)?shù)臅r(shí)候進(jìn)行重傳操作。

apiflags值為NETCONN_NOAUTORCVD時(shí),表示在TCP協(xié)議接收到數(shù)據(jù)的時(shí)候,調(diào)用netconn_recv_data_tcp()函數(shù)的時(shí)候不會(huì)去更新接收窗口,只能由用戶自己調(diào)用netconn_tcp_recvd()函數(shù)完成接收窗口的更新操作。

了解了以上3個(gè)API,我們開始創(chuàng)建Client工程:

static void client(void* thread_param)
{
    struct netconn* conn;
    int ret;
    ip4_addr_t ipaddr;
    uint8_t send_buf[] = "This is MM32F3270 TCP Client Demon";         //(1)
    while(1) {
        conn = netconn_new(NETCONN_TCP);                       //(2)
        if (conn == NULL) {                                       // (3)
            printf("create conn failed!n");
            vTaskDelay(10);
            continue;
        }
        IP4_ADDR( ipaddr, DEST_IP_ADDR0, DEST_IP_ADDR1, DEST_IP_ADDR2, DEST_IP_ADDR3);                                           // (4)
        ret = netconn_connect(conn,  ipaddr, DEST_PORT);      // (5)
        if (ret == -1) {
            printf("Connect failed!n");
            netconn_close(conn);
            vTaskDelay(10);
            continue;
        }
        while (1) {
            ret = netconn_write(conn, send_buf, sizeof(send_buf), 0);  // (6)
            vTaskDelay(1000);
        }
    }

}

1)將需要發(fā)送的數(shù)據(jù)裝填進(jìn)send_buf中

2)申請(qǐng)一個(gè)內(nèi)存區(qū)域,類型為TCP

3)如果conn為空表示申請(qǐng)內(nèi)存失敗

4)將地址賦值給ipaddr

5)創(chuàng)建連接,如果失敗則刪除conn

6)執(zhí)行數(shù)據(jù)發(fā)送

到這里已經(jīng)完成了工程的創(chuàng)建,但是還有一步比較重要的,配置我們的IP,將數(shù)據(jù)發(fā)送給服務(wù)器端,則需要知道服務(wù)器的地址。打開命令行窗口輸入:ipconfig

pYYBAGIB1TOARaWcAAEnlBhO5H8936.png

PC地址為:192.168.105.34,在sys_arch.h文件中對(duì)DEST_IP_ADDR0 、DEST_IP_ADDR1、DEST_IP_ADDR2、DEST_IP_ADDR3進(jìn)行修改,DEST_PORT隨意修改,值得注意的同一個(gè)設(shè)備是如果創(chuàng)建多個(gè)網(wǎng)卡,PORT成不同的值即可,后面我們會(huì)進(jìn)行這類實(shí)驗(yàn),設(shè)備IP需要設(shè)置在同一個(gè)網(wǎng)段內(nèi)通信才能進(jìn)行IP_ADDR0、IP_ADDR1、IP_ADDR2,需要與PC地址保持一致,IP_ADDR3可以隨意設(shè)置(和PC地址不一致即可)。

#define DEST_IP_ADDR0               192
#define DEST_IP_ADDR1               168
#define DEST_IP_ADDR2               105
#define DEST_IP_ADDR3               34

#define DEST_PORT                  5001

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

將程序下載入開發(fā)板中,使用SSCOM工具進(jìn)行如下設(shè)置:

poYBAGIB136AUNEzAAF-Q-Sbt_k799.png

點(diǎn)擊偵聽:

poYBAGIB14CAOSBcAAKTfLZKCLA036.png

可以正常偵聽并接收到數(shù)據(jù),表明實(shí)驗(yàn)成功。實(shí)驗(yàn)程序請(qǐng)登錄我們的官網(wǎng)下載MM32F3270 SDK,工程路徑如下:

~MM32F3270_Lib_Samples_V0.90Demo_appEthernet_DemoETH_RTOSFreertos_Client

來源:靈動(dòng)MM32MCU


審核編輯:湯梓紅

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 以太網(wǎng)
    +關(guān)注

    關(guān)注

    41

    文章

    5642

    瀏覽量

    176065
  • Socket
    +關(guān)注

    關(guān)注

    1

    文章

    212

    瀏覽量

    35886
  • TCP
    TCP
    +關(guān)注

    關(guān)注

    8

    文章

    1402

    瀏覽量

    81111
  • FreeRTOS
    +關(guān)注

    關(guān)注

    12

    文章

    493

    瀏覽量

    64392
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    靈動(dòng)微課堂 (第184講) | 基于MM32F3270 以太網(wǎng) UDP使用

    _Lib_Samples_V0.90\Demo_app\Ethernet_Demo\ETH_RTOS\Freertos_UDP我們下節(jié)的題目為《基于MM32F3270以太網(wǎng)Client的使用》。
    發(fā)表于 10-18 11:13

    靈動(dòng)微課堂 (第185講) | 基于MM32F3270 以太網(wǎng) Client使用

    前面介紹了基于Socket方式的以太網(wǎng)通訊,接下來給大家介紹基于TCP包的通訊。內(nèi)容分為基于MM32F3270以太網(wǎng)Client的使用與基于MM32
    發(fā)表于 10-18 11:21

    MM32F3270系列32位MCU的特點(diǎn)有哪些

    上海靈動(dòng)微電子推出全新主流型MM32F3270系列32位MCU,此款MM32F3270系列是基于M3內(nèi)核的32位微控制器,MM32F3270適用于要求高集成度的高性能控制領(lǐng)域,如:工業(yè)控制、消防監(jiān)控
    發(fā)表于 11-03 07:20

    靈動(dòng)微電子MM32F3270系列MCU的特點(diǎn)介紹

    上海靈動(dòng)微電子推出全新主流型MM32F3270系列32位MCU,此款MM32F3270系列是基于M3內(nèi)核的32位微控制器,MM32F3270適用于要求高集成度的高性能控制領(lǐng)域,如:工業(yè)控制、消防監(jiān)控
    發(fā)表于 03-22 16:57 ?2332次閱讀

    【國(guó)產(chǎn)MCU移植】MM32F3270 EVBoard

    【國(guó)產(chǎn)MCU移植】MM32F3270 EVBoard
    發(fā)表于 12-03 17:21 ?5次下載
    【國(guó)產(chǎn)MCU移植】<b class='flag-5'>MM32F3270</b> EVBoard

    基于MM32F3270 以太網(wǎng) Client使用

    接下來給大家介紹基于TCP包的通訊。內(nèi)容分為基于MM32F3270以太網(wǎng)Client的使用與基于MM32F3270以太網(wǎng)Server的使用。
    發(fā)表于 02-08 15:10 ?0次下載
    基于<b class='flag-5'>MM32F3270</b> <b class='flag-5'>以太網(wǎng)</b> <b class='flag-5'>Client</b>使用

    MM32F3270 勘誤表(中文版)

    MM32F3270 勘誤表(中文版)
    發(fā)表于 02-23 18:42 ?0次下載
    <b class='flag-5'>MM32F3270</b> 勘誤表(中文版)

    MM32F3270 ADC注入通道

    MM32F3270 ADC注入通道
    的頭像 發(fā)表于 09-27 15:59 ?1370次閱讀
    <b class='flag-5'>MM32F3270</b> ADC注入通道

    使用MM32F3270 FSMC驅(qū)動(dòng)OLED

    使用MM32F3270 FSMC驅(qū)動(dòng)OLED
    的頭像 發(fā)表于 09-27 15:30 ?1494次閱讀
    使用<b class='flag-5'>MM32F3270</b> FSMC驅(qū)動(dòng)OLED

    使用MM32F3270 FSMC驅(qū)動(dòng)TFT-LCD

    使用MM32F3270 FSMC驅(qū)動(dòng)TFT-LCD
    的頭像 發(fā)表于 09-27 15:34 ?1777次閱讀
    使用<b class='flag-5'>MM32F3270</b> FSMC驅(qū)動(dòng)TFT-LCD

    基于MM32F3270以太網(wǎng)HTTP使用

    基于MM32F3270以太網(wǎng)HTTP使用
    的頭像 發(fā)表于 09-27 15:48 ?855次閱讀
    基于<b class='flag-5'>MM32F3270</b><b class='flag-5'>以太網(wǎng)</b>HTTP使用

    基于MM32F3270以太網(wǎng)Server使用

    基于MM32F3270以太網(wǎng)Server使用
    的頭像 發(fā)表于 09-27 15:46 ?760次閱讀
    基于<b class='flag-5'>MM32F3270</b><b class='flag-5'>以太網(wǎng)</b>Server使用

    基于MM32F3270以太網(wǎng)UDP使用

    基于MM32F3270以太網(wǎng) UDP使用
    的頭像 發(fā)表于 09-27 15:42 ?808次閱讀
    基于<b class='flag-5'>MM32F3270</b><b class='flag-5'>以太網(wǎng)</b>UDP使用

    基于MM32F3270以太網(wǎng)Server_Socket使用

    基于MM32F3270以太網(wǎng)Server_Socket使用
    的頭像 發(fā)表于 09-27 15:41 ?749次閱讀
    基于<b class='flag-5'>MM32F3270</b><b class='flag-5'>以太網(wǎng)</b>Server_Socket使用

    基于MM32F3270以太網(wǎng)Client_Socket使用

    基于MM32F3270以太網(wǎng)Client_Socket使用
    的頭像 發(fā)表于 09-27 15:37 ?826次閱讀
    基于<b class='flag-5'>MM32F3270</b><b class='flag-5'>以太網(wǎng)</b><b class='flag-5'>Client</b>_Socket使用