那曲檬骨新材料有限公司

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

基于MM32F3270以太網Client_Socket使用

jf_pJlTbmA9 ? 來源:靈動MM32MCU ? 作者:靈動MM32MCU ? 2023-09-27 15:37 ? 次閱讀

在進行本節之前,首先解決大家的一個疑惑點:Client和Client_Socket有什么區別或分別代表的含義?

Socket標準定義為套接字,應用于主流的網絡設計程序,具有使用簡單,多平臺移植方便的特點。在Socket應用中,使用一個套接字來記錄網絡的一個連接,套接字是一個整數,就像操作文件一樣,利用一個文件描述符,進行打開、讀、寫、關閉等操作。在網絡中,可以對Socket 套接字進行類似的操作,比如開啟一個網絡的連接、讀取連接主機發送來的數據、向連接的主機發送數據、終止連接等操作。LwIP設計目的主要應用于嵌入式平臺,對于Socket的支持并不完全,只是通過對netconn進行封裝實現部分功能,使得LwIP也具有多平臺應用的特性,通過Socket方式的了解能夠極大簡化通信過程的理解,快速實現應用開發。

Demo應用中,使用的開發板為MB-039,在工程中使用LwIP+FreeRTOS,實驗展示如何制作一個客戶端并發送數據,板載Ethernet相關的硬件部分電路如下:

poYBAGIB1SyAHYynAAG39uXw7q0489.png

MB-039 完整原理圖可以通過MM32官網下載

各個信號引腳對應如下:

poYBAGIB2UaAVvRCAAAOaXXYgy8012.png
poYBAGIB1TGAFwREAAi12qR49zc411.png

通過配置復用相關引腳為RMII相關的功能,初始化以太網功能,執行FreeRTOS的啟動。具體過程可參考樣例初始化程序中代碼。

在進行Client_Socket實驗前,我們先了解需要使用到的應用功能函數:

(1)socket ()

(2)connect ()

(3)write ()

(1) socket ()

Socket()指向lwip_socket(),功能為申請一個套接字,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;
}

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

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

2. SOCK_DGRAM:是提供無保障的面向消息的Socket服務,主要用于在網絡上發廣播信息,如UDP協議,提供無連接不可靠的數據報交付服務。

3. SOCK_RAW:表示原始套接字,它允許應用程序訪問網絡層的原始數據包,這個套接字用得比較少,暫時不用理會它。

Protocol指定套接字使用的協議,對于IPv4,TCP協議提供SOCK_STREAM服務,只有UDP協議提供SOCK_DGRAM服務。

(2) connect ()

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

(3) write ()

Write()指向lwip_write,源碼如下,其通過調用lwip_send實現,flags為0。

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

了解了以上3個API,接下來開始創建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)申請一個套接字:socket

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

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

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

(5)創建連接,將sock與地址端口進行綁定,建立連接

(6)發送數據

到這里已經完成了Client Socket工程的創建,還有一步比較重要的是配置Client與Server端的IP,將數據發送給服務器端。

在Windows下,通過打開命令行窗口輸入: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可選用空閑端口,設備IP需要設置在同一個網段內通信才能進行IP_ADDR0、IP_ADDR1 、IP_ADDR2,需要與PC地址保持一致,IP_ADDR3可以隨意設置(和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

將程序下載入開發板中,使用SSCOM工具進行如下設置:

poYBAGIB136AUNEzAAF-Q-Sbt_k799.png

點擊偵聽:

poYBAGIB2U6AWLYcAAKCmWm26yU275.png

可以觀察到正常偵聽并接收到數據,表明實驗成功。Demo程序可登錄MindMotion的官網下載MM32F3270 lib_Samples。

來源:靈動MM32MCU


審核編輯:湯梓紅

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 嵌入式
    +關注

    關注

    5092

    文章

    19177

    瀏覽量

    307663
  • 以太網
    +關注

    關注

    40

    文章

    5460

    瀏覽量

    172726
  • 開發板
    +關注

    關注

    25

    文章

    5121

    瀏覽量

    98193
  • FreeRTOS
    +關注

    關注

    12

    文章

    484

    瀏覽量

    62395
收藏 人收藏

    評論

    相關推薦

    靈動微課堂 (第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的使用與基于
    發表于 10-18 11:21

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

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

    【國產MCU移植】MM32F3270 EVBoard

    【國產MCU移植】MM32F3270 EVBoard
    發表于 12-03 17:21 ?5次下載
    【國產MCU移植】<b class='flag-5'>MM32F3270</b> EVBoard

    基于MM32F3270 以太網 Client使用

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

    基于MM32F3270 以太網 Server_Socket使用

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

    基于MM32F3270以太網 Client_Socket使用

    Socket標準定義為套接字,應用于主流的網絡設計程序,具有使用簡單,多平臺移植方便的特點
    發表于 02-08 15:20 ?0次下載
    基于<b class='flag-5'>MM32F3270</b><b class='flag-5'>以太網</b> <b class='flag-5'>Client_Socket</b>使用

    MM32F3270 ADC注入通道

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

    使用MM32F3270 FSMC驅動OLED

    使用MM32F3270 FSMC驅動OLED
    的頭像 發表于 09-27 15:30 ?1015次閱讀
    使用<b class='flag-5'>MM32F3270</b> FSMC驅動OLED

    基于MM32F3270以太網HTTP使用

    基于MM32F3270以太網HTTP使用
    的頭像 發表于 09-27 15:48 ?608次閱讀
    基于<b class='flag-5'>MM32F3270</b><b class='flag-5'>以太網</b>HTTP使用

    基于MM32F3270以太網Server使用

    基于MM32F3270以太網Server使用
    的頭像 發表于 09-27 15:46 ?541次閱讀
    基于<b class='flag-5'>MM32F3270</b><b class='flag-5'>以太網</b>Server使用

    基于MM32F3270以太網Client使用

    基于MM32F3270以太網Client使用
    的頭像 發表于 09-27 15:44 ?746次閱讀
    基于<b class='flag-5'>MM32F3270</b><b class='flag-5'>以太網</b><b class='flag-5'>Client</b>使用

    基于MM32F3270以太網UDP使用

    基于MM32F3270以太網 UDP使用
    的頭像 發表于 09-27 15:42 ?543次閱讀
    基于<b class='flag-5'>MM32F3270</b><b class='flag-5'>以太網</b>UDP使用

    基于MM32F3270以太網Server_Socket使用

    基于MM32F3270以太網Server_Socket使用
    的頭像 發表于 09-27 15:41 ?505次閱讀
    基于<b class='flag-5'>MM32F3270</b><b class='flag-5'>以太網</b>Server_<b class='flag-5'>Socket</b>使用
    澳门百家乐必胜看| 网上百家乐骗人的吗| 百家乐官网真人游戏网上投注 | 百家乐赌博规律| 全讯网百家乐官网的玩法技巧和规则| 呼伦贝尔市| 大发888注册步骤| 百家乐伴侣破解版| 百家乐投注法则| 百家乐官网小路单图解| 百家乐官网真人游戏开户| 足彩大赢家| 全讯网365| 百家乐怎么玩最保险| 适合做生意的开运方法| 百家乐官网扎金花斗地主| 赌百家乐官网咋赢对方| 888真人赌博| 大发888游戏官方下| 百家乐真人百家乐赌博| 保时捷百家乐娱乐城| 百家乐官网麻将牌| 电脑版百家乐官网分析仪| 彰化县| 六合彩生肖表| 大发888手机版下载安| 太阳城丝巾| 金榜百家乐的玩法技巧和规则| 真人百家乐开户优惠| 百家乐数据程序| 大连百家乐官网商场| 娱百家乐官网下载| 百家乐官网讯特| 百家乐官网电脑游戏高手| 托里县| 六合彩开奖结果查询| 大发888新址 | 专栏| 舒兰市| 奉新县| 通渭县|