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_Socket使用

jf_pJlTbmA9 ? 來源:靈動(dòng)MM32MCU ? 作者:靈動(dòng)MM32MCU ? 2023-09-27 15:37 ? 次閱讀

在進(jìn)行本節(jié)之前,首先解決大家的一個(gè)疑惑點(diǎn):Client和Client_Socket有什么區(qū)別或分別代表的含義?

Socket標(biāo)準(zhǔn)定義為套接字,應(yīng)用于主流的網(wǎng)絡(luò)設(shè)計(jì)程序,具有使用簡單,多平臺(tái)移植方便的特點(diǎn)。在Socket應(yīng)用中,使用一個(gè)套接字來記錄網(wǎng)絡(luò)的一個(gè)連接,套接字是一個(gè)整數(shù),就像操作文件一樣,利用一個(gè)文件描述符,進(jìn)行打開、讀、寫、關(guān)閉等操作。在網(wǎng)絡(luò)中,可以對(duì)Socket 套接字進(jìn)行類似的操作,比如開啟一個(gè)網(wǎng)絡(luò)的連接、讀取連接主機(jī)發(fā)送來的數(shù)據(jù)、向連接的主機(jī)發(fā)送數(shù)據(jù)、終止連接等操作。LwIP設(shè)計(jì)目的主要應(yīng)用于嵌入式平臺(tái),對(duì)于Socket的支持并不完全,只是通過對(duì)netconn進(jìn)行封裝實(shí)現(xiàn)部分功能,使得LwIP也具有多平臺(tái)應(yīng)用的特性,通過Socket方式的了解能夠極大簡化通信過程的理解,快速實(shí)現(xiàn)應(yīng)用開發(fā)。

Demo應(yīng)用中,使用的開發(fā)板為MB-039,在工程中使用LwIP+FreeRTOS,實(shí)驗(yàn)展示如何制作一個(gè)客戶端并發(fā)送數(shù)據(jù),板載Ethernet相關(guān)的硬件部分電路如下:

poYBAGIB1SyAHYynAAG39uXw7q0489.png

MB-039 完整原理圖可以通過MM32官網(wǎng)下載。

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

poYBAGIB2UaAVvRCAAAOaXXYgy8012.png
poYBAGIB1TGAFwREAAi12qR49zc411.png

通過配置復(fù)用相關(guān)引腳為RMII相關(guān)的功能,初始化以太網(wǎng)功能,執(zhí)行FreeRTOS的啟動(dòng)。具體過程可參考樣例初始化程序中代碼。

在進(jìn)行Client_Socket實(shí)驗(yàn)前,我們先了解需要使用到的應(yīng)用功能函數(shù):

(1)socket ()

(2)connect ()

(3)write ()

(1) socket ()

Socket()指向lwip_socket(),功能為申請(qǐng)一個(gè)套接字,lwip_socket()源碼如下:

int
lwip_socket(int domain, int type, int protocol)
{
  struct netconn *conn;
  int i;

  LWIP_UNUSED_ARG(domain); /* @todo: check this */

  /* create a netconn */
  switch (type) {
    case SOCK_RAW:
      conn = netconn_new_with_proto_and_callback(DOMAIN_TO_NETCONN_TYPE(domain, NETCONN_RAW),
             (u8_t)protocol, DEFAULT_SOCKET_EVENTCB);
      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%s, SOCK_RAW, %d) = ",
                                  domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol));
      break;
    case SOCK_DGRAM:
      conn = netconn_new_with_callback(DOMAIN_TO_NETCONN_TYPE(domain,
                                       ((protocol == IPPROTO_UDPLITE) ? NETCONN_UDPLITE : NETCONN_UDP)),
                                       DEFAULT_SOCKET_EVENTCB);
      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%s, SOCK_DGRAM, %d) = ",
                                  domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol));
#if LWIP_NETBUF_RECVINFO
      if (conn) {
        /* netconn layer enables pktinfo by default, sockets default to off */
        conn->flags  = ~NETCONN_FLAG_PKTINFO;
      }
#endif /* LWIP_NETBUF_RECVINFO */
      break;
    case SOCK_STREAM:
      conn = netconn_new_with_callback(DOMAIN_TO_NETCONN_TYPE(domain, NETCONN_TCP), DEFAULT_SOCKET_EVENTCB);
      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%s, SOCK_STREAM, %d) = ",
                                  domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol));
      break;
    default:
      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%d, %d/UNKNOWN, %d) = -1n",
                                  domain, type, protocol));
      set_errno(EINVAL);
      return -1;
  }

  if (!conn) {
    LWIP_DEBUGF(SOCKETS_DEBUG, ("-1 / ENOBUFS (could not create netconn)n"));
    set_errno(ENOBUFS);
    return -1;
  }

  i = alloc_socket(conn, 0);

  if (i == -1) {
    netconn_delete(conn);
    set_errno(ENFILE);
    return -1;
  }
  conn->socket = i;
  done_socket( sockets[i - LWIP_SOCKET_OFFSET]);
  LWIP_DEBUGF(SOCKETS_DEBUG, ("%dn", i));
  set_errno(0);
  return i;
}

從源碼中我們可以看出,本質(zhì)上是對(duì)netconn_new()進(jìn)行封裝。我們關(guān)注一下其參數(shù),domain表示協(xié)議簇,對(duì)于IP/TCP來說該值始終為AF_INET。重點(diǎn)需要關(guān)注一下type,我們查看API手冊(cè)對(duì)于幾種類型的解釋如下:

1. SOCK_STREAM:提供可靠的(即能保證數(shù)據(jù)正確傳送到對(duì)方)面向連接Socket服務(wù),多用于資料(如文件)傳輸,如TCP協(xié)議。

2. SOCK_DGRAM:是提供無保障的面向消息的Socket服務(wù),主要用于在網(wǎng)絡(luò)上發(fā)廣播信息,如UDP協(xié)議,提供無連接不可靠的數(shù)據(jù)報(bào)交付服務(wù)。

3. SOCK_RAW:表示原始套接字,它允許應(yīng)用程序訪問網(wǎng)絡(luò)層的原始數(shù)據(jù)包,這個(gè)套接字用得比較少,暫時(shí)不用理會(huì)它。

Protocol指定套接字使用的協(xié)議,對(duì)于IPv4,TCP協(xié)議提供SOCK_STREAM服務(wù),只有UDP協(xié)議提供SOCK_DGRAM服務(wù)。

(2) connect ()

connect()指向lwip_connect()(源碼較長,就不進(jìn)行粘貼了),函數(shù)的作用與前文介紹netconn_connect功能一致,通過源碼可以知道其是通過對(duì)netconn_connect的封裝實(shí)現(xiàn)。在TCP客戶端連接中,調(diào)用這個(gè)函數(shù)將發(fā)生握手過程,并最終建立新的TCP連接。對(duì)于UDP來說調(diào)用這個(gè)函數(shù)只是在UDP控制塊中記錄遠(yuǎn)端IP地址與端口號(hào)。

(3) write ()

Write()指向lwip_write,源碼如下,其通過調(diào)用lwip_send實(shí)現(xiàn),flags為0。

ssize_t
lwip_write(int s, const void *data, size_t size)
{
  return lwip_send(s, data, size, 0);
}

了解了以上3個(gè)API,接下來開始創(chuàng)建Client_Socket工程:

static void client(void *thread_param)
{
  int sock = -1;
  struct sockaddr_in client_addr;  
  ip4_addr_t ipaddr;  
  uint8_t send_buf[]= " This is MM32F3270 TCP Client_Socket Demo n";

  IP4_ADDR( ipaddr,DEST_IP_ADDR0,DEST_IP_ADDR1,DEST_IP_ADDR2,DEST_IP_ADDR3);
  while(1)
  {
    sock = socket(AF_INET, SOCK_STREAM, 0);    //(1)
    if (sock < 0)
    {
      vTaskDelay(10);
      continue;
    } 

    client_addr.sin_family = AF_INET;           //(2)
    client_addr.sin_port = htons(DEST_PORT);   //(3)
    client_addr.sin_addr.s_addr = ipaddr.addr;   //(4)
    memset( (client_addr.sin_zero), 0, sizeof(client_addr.sin_zero));    

    if (connect(sock, 
               (struct sockaddr *) client_addr, 
                sizeof(struct sockaddr)) == -1)    //(5)
    {
        printf("Connect failed!n");
        closesocket(sock);
        vTaskDelay(10);
        continue;
    }                                               
    while (1)
    {
      if(write(sock,send_buf,sizeof(send_buf)) < 0)   //(6)
        break; 
      vTaskDelay(1000);
    } 
    closesocket(sock);
  }
}

(1)申請(qǐng)一個(gè)套接字:socket

(2)協(xié)議簇類型(AF_INET用于TCP/IP協(xié)議)

(3)將端口賦值給client_addr的sin_port成員

(4)將地址賦值給client_addr的sin_addr.s_addr成員

(5)創(chuàng)建連接,將sock與地址端口進(jìn)行綁定,建立連接

(6)發(fā)送數(shù)據(jù)

到這里已經(jīng)完成了Client Socket工程的創(chuàng)建,還有一步比較重要的是配置Client與Server端的IP,將數(shù)據(jù)發(fā)送給服務(wù)器端。

在Windows下,通過打開命令行窗口輸入:ipconfig可以獲取本機(jī)地址與服務(wù)器的地址。

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可選用空閑端口,設(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                    130

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

poYBAGIB136AUNEzAAF-Q-Sbt_k799.png

點(diǎn)擊偵聽:

poYBAGIB2U6AWLYcAAKCmWm26yU275.png

可以觀察到正常偵聽并接收到數(shù)據(jù),表明實(shí)驗(yàn)成功。Demo程序可登錄MindMotion的官網(wǎng)下載MM32F3270 lib_Samples。

來源:靈動(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)投訴
  • 嵌入式
    +關(guān)注

    關(guān)注

    5045

    文章

    18816

    瀏覽量

    298442
  • 以太網(wǎng)
    +關(guān)注

    關(guān)注

    40

    文章

    5287

    瀏覽量

    169633
  • 開發(fā)板
    +關(guān)注

    關(guān)注

    25

    文章

    4771

    瀏覽量

    96154
  • FreeRTOS
    +關(guān)注

    關(guān)注

    12

    文章

    483

    瀏覽量

    61721
收藏 人收藏

    評(píng)論

    相關(guān)推薦

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

    :~\MM32F3270_Lib_Samples_V0.90\Demo_app\Ethernet_Demo\ETH_RTOS\Freertos_Client_socket下章的題目為《基于MM32F3270
    發(fā)表于 10-18 11:02

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

    :~\MM32F3270_Lib_Samples_V0.90\Demo_app\Ethernet_Demo\ETH_RTOS\Freertos_Server_socket我們下節(jié)的題目為《基于MM32F3270
    發(fā)表于 10-18 11:08

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

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

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

    【國產(chǎn)MCU移植】MM32F3270 EVBoard
    發(fā)表于 12-03 17:21 ?5次下載
    【國產(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 以太網(wǎng) Server_Socket使用

    本節(jié)通過Socket的方式對(duì)整個(gè)通信過程再次進(jìn)行一次整理(使用Socket方式易于加深對(duì)以太網(wǎng)通信過程的理解,在此講解使用的是完整版Socket)。
    發(fā)表于 02-08 15:17 ?0次下載
    基于<b class='flag-5'>MM32F3270</b> <b class='flag-5'>以太網(wǎng)</b> Server_<b class='flag-5'>Socket</b>使用

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

    Socket標(biāo)準(zhǔn)定義為套接字,應(yīng)用于主流的網(wǎng)絡(luò)設(shè)計(jì)程序,具有使用簡單,多平臺(tái)移植方便的特點(diǎn)
    發(fā)表于 02-08 15:20 ?0次下載
    基于<b class='flag-5'>MM32F3270</b><b class='flag-5'>以太網(wǎng)</b> <b class='flag-5'>Client_Socket</b>使用

    MM32F3270 ADC注入通道

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

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

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

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

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

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

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

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

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