娇小w搡bbbb搡bbb,《第一次の人妻》,中国成熟妇女毛茸茸,边啃奶头边躁狠狠躁视频免费观看

歷史上的今天

今天是:2025年03月11日(星期二)

正在發生

2020年03月11日 | STM32開發筆記70: 傳遞參數對套接字地址進行強制類型轉換

發布者:忠正 來源: eefocus關鍵字:STM32  傳遞參數  套接字地址  強制類型轉換 手機看文章 掃描二維碼
隨時隨地手機看文章

單片機型號:STM32F407VGT6


在進行IPV6的UDP設計時,偶然發現一個問題,就是大部分套接字函數都需對地址進行強制轉換,先看一下程序


這是bind函數:


bind(sockIPV6, (struct sockaddr*)&sockAddr, sizeof(sockAddr))

這是recvfrom函數:


recvfrom(sockIPV6, UdpBuffer, 100, 0, (struct sockaddr*)&sockAddr, &slen)

這是sendto函數:


sendto(sockIPV6, UdpBuffer, len, 0, (const struct sockaddr*)&sockAddr, sizeof(sockAddr))

無一例外,這些函數在處理sockAddr之前都進行了強制數據類型轉換,將其轉換為sockaddr。


這個問題,在進行IPV4設計時,稀里糊涂的就過去了,沒有深究過,今天在寫IPV6時,疑惑就比較大了。


在IPV6中,sockAddr定義的數據類型是sockaddr_in6,在IPV4中定義的數據類型是sockaddr_in,為何能轉換成同一數據類型呢?仔細分析后,發現里面有很大的玄機。


sockaddr_in的定義:


struct sockaddr_in {

  u8_t            sin_len;

  sa_family_t     sin_family;

  in_port_t       sin_port;

  struct in_addr  sin_addr;

#define SIN_ZERO_LEN 8

  char            sin_zero[SIN_ZERO_LEN];

};

sin_len:1字節,指明結構體有用數據的長度


sin_family:1字節,表示結構體的Family類型,指明是IPV4,還是IPV6


sin_port:2字節,端口號


sin_addr:4字節,IP地址


sin_zero:8字節,占位用


合計:16字節


sockaddr_in6的定義:


struct sockaddr_in6 {

  u8_t            sin6_len;      /* length of this structure    */

  sa_family_t     sin6_family;   /* AF_INET6                    */

  in_port_t       sin6_port;     /* Transport layer port #      */

  u32_t           sin6_flowinfo; /* IPv6 flow information       */

  struct in6_addr sin6_addr;     /* IPv6 address                */

  u32_t           sin6_scope_id; /* Set of interfaces for scope */

}

sin6_len:1字節,指明結構體有用數據的長度


sin6_family:1字節,表示結構體的Family類型,指明是IPV4,還是IPV6


sin6_port:2字節,端口號


sin6_flowinfo:4字節,包含IPV6報頭中的通信流類別字段和流標簽字段


sin6_addr:16字節,IPV6地址


sin6_scope_id:4字節,包含了范圍ID,它用于標識一系列的接口,這些接口與地址字段中的地址相對應


合計:28字節


sockaddr的定義:


struct sockaddr {

  u8_t        sa_len;

  sa_family_t sa_family;

  char        sa_data[14];

};

sin_len:1字節,指明結構體有用數據的長度


sin_family:1字節,表示結構體的Family類型,指明是IPV4,還是IPV6


sa_data:14字節,占位用


合計:16字節


將sockaddr_in和sockaddr_in6轉換為sockaddr是為保證代碼的統一性,這樣做后,socket中函數就可以采用統一的格式進行調用。


LwIP在進行初始設計時,本身不支持IPV6,所以將sockaddr_in和sockaddr定義為相同的長度。


在windows操作系統中,這3個結構體定義的長度是一致的的,都是28字節。


如果,這樣問題又來了,在LwIP中sockaddr_in6和sockaddr長度不一致,是如何完成轉換的呢?


我們那一個socket函數進行分析就好,例如我們選擇bind函數,其內部定義如下:


int

lwip_bind(int s, const struct sockaddr *name, socklen_t namelen)

{

  struct lwip_sock *sock;

  ip_addr_t local_addr;

  u16_t local_port;

  err_t err;

 

  sock = get_socket(s);

  if (!sock) {

    return -1;

  }

 

  if (!SOCK_ADDR_TYPE_MATCH(name, sock)) {

    /* sockaddr does not match socket type (IPv4/IPv6) */

    sock_set_errno(sock, err_to_errno(ERR_VAL));

    return -1;

  }

 

  /* check size, family and alignment of 'name' */

  LWIP_ERROR("lwip_bind: invalid address", (IS_SOCK_ADDR_LEN_VALID(namelen) &&

             IS_SOCK_ADDR_TYPE_VALID(name) && IS_SOCK_ADDR_ALIGNED(name)),

             sock_set_errno(sock, err_to_errno(ERR_ARG)); return -1;);

  LWIP_UNUSED_ARG(namelen);

 

  SOCKADDR_TO_IPADDR_PORT(name, &local_addr, local_port);

  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_bind(%d, addr=", s));

  ip_addr_debug_print_val(SOCKETS_DEBUG, local_addr);

  LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F")n", local_port));

 

#if LWIP_IPV4 && LWIP_IPV6

  /* Dual-stack: Unmap IPv4 mapped IPv6 addresses */

  if (IP_IS_V6_VAL(local_addr) && ip6_addr_isipv4mappedipv6(ip_2_ip6(&local_addr))) {

    unmap_ipv4_mapped_ipv6(ip_2_ip4(&local_addr), ip_2_ip6(&local_addr));

    IP_SET_TYPE_VAL(local_addr, IPADDR_TYPE_V4);

  }

#endif /* LWIP_IPV4 && LWIP_IPV6 */

 

  err = netconn_bind(sock->conn, &local_addr, local_port);

 

  if (err != ERR_OK) {

    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_bind(%d) failed, err=%dn", s, err));

    sock_set_errno(sock, err_to_errno(err));

    return -1;

  }

 

  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_bind(%d) succeededn", s));

  sock_set_errno(sock, 0);

  return 0;

}


可以看到,對于sockaddr其使用指針進行傳遞的。有關name的處理有很多函數,我們通過字面上理解,可定位于下面的宏。


SOCKADDR_TO_IPADDR_PORT(name, &local_addr, local_port);

繼續找到其具體定義:


#define SOCKADDR_TO_IPADDR_PORT(sockaddr, ipaddr, port) sockaddr_to_ipaddr_port(sockaddr, ipaddr, &(port))

再找到sockaddr_to_ipaddr_port的具體定義:


static void

sockaddr_to_ipaddr_port(const struct sockaddr* sockaddr, ip_addr_t* ipaddr, u16_t* port)

{

  if ((sockaddr->sa_family) == AF_INET6) {

    SOCKADDR6_TO_IP6ADDR_PORT((const struct sockaddr_in6*)(const void*)(sockaddr), ipaddr, *port);

    ipaddr->type = IPADDR_TYPE_V6;

  } else {

    SOCKADDR4_TO_IP4ADDR_PORT((const struct sockaddr_in*)(const void*)(sockaddr), ipaddr, *port);

    ipaddr->type = IPADDR_TYPE_V4;

  }

}


到這里,我們就看的很清楚了,通過sockaddr_to_ipaddr_port函數,再強制轉換為相應的結構體。

關鍵字:STM32  傳遞參數  套接字地址  強制類型轉換 引用地址:STM32開發筆記70: 傳遞參數對套接字地址進行強制類型轉換

上一篇:STM32開發筆記71: 解決FreeRTOS任務的內存分配問題
下一篇:STM32開發筆記69: 外設啟動的先后次序

推薦閱讀

高通和Qualcomm與TDK的合資企業RF360控股新加坡有限公司(“RF360控股公司”)率先發布一款包含最新體聲波(BAW)和表面聲波(SAW)濾波技術的六工器射頻解決方案,支持最佳的性能、尺寸和成本,以應對日益復雜的頻率、頻段組合。全新的六工器解決方案完善了我們的濾波器、雙工器和多工器產品線,可應對運營商部署的各種載波聚合配置,在其擴展千兆級LTE覆...
美中貿易紛爭影響浮現,受到不少供應鏈移轉產線及終端應用需求急凍影響,讓DRAM、被動元件和硅晶圓等去年三大最夯電子元件首季價格全數下跌,其中DRAM和被動元件跌速達三成,超乎預期,硅晶圓價格也確定下季跟進,凸顯整體半導體和電子產業上半年營運,因全球景氣放緩持續向下修正。DRAM、被動元件和硅晶圓過去兩年漲勢驚人,DRAM產業在寡...
在近期疫情防控和復工復產工作中,城市能源信息分析發揮了決策支持作用。預計未來,人們會更重視城市能源信息對城市公共服務的價值作用。本文對城市能源信息平臺的現狀作了分析,并對其未來更好地促進城市精細化治理,并對新型智慧城市建設發揮支撐作用提出了相關建議。 ?雄安市民服務中心智慧能源管控系統。程佳佳 攝 霍沫霖 在浙江、江蘇、...
智能系統連接解決方案的先驅Astera Labs宣布拓展其關注領域,目的是解決以數據為中心(data-centric)的應用系統的性能瓶頸。全新的Aries Compute Express Link?(CXL? 2.0)Smart Retimer(PT5161LX、PT5081LX)產品系列是面向低時延的CXL.io連接方案,是其布局新領域的首款解決方案,目前正積極與戰略性客戶進行樣品驗證。 Astera Labs首席執行...

史海拾趣

問答坊 | AI 解惑

systemc的資料

我的個人博客,里面收集了些軟件方面的東西。 micbot.com 希望大家喜歡。…

查看全部問答∨

嵌入式系統中,DRAM減少一半,需要對系統內核的哪些部分進行修改

為了保證部分功能的實時性要求,我覺得可能需要對 系統的進程的搶斷機制,還有內存分頁等進行修改。 請問,還需要注意哪些問題,謝謝。…

查看全部問答∨

困惑,得不到數據包協議類型

Packet = PacketArray;         NdisQueryPacket(Packet,NULL,&BufLength,&pBuffer,&PacketSize);         if(!BufLength)            ...…

查看全部問答∨

如何將游戲模擬器移植到ARM的平臺?(重金酬謝)

我現在開發的過程中遇到了這樣的問題,如何將任天堂(NES)游戲模擬器,移植到我們的平臺上。     我們用的是ARM9 的CPU,和LINUX操作系統,或者THREADX上也可以~~ 如果誰會的話,將重金酬謝!! (只要能將任意一款任天堂的游戲,在 ...…

查看全部問答∨

一款價廉物美的ARM7開發板

大家好:我們公司是專業做ARM開發板的,目前開發的ST ARM7(STR71*)系列開發板非常適合廣大學生、電子愛好者等學習、研究。  ARM_STR710教學實驗開發平臺支持UC/OS和NUCLEUS PLUS雙操作系統,提供專業的工程模塊,方便用 ...…

查看全部問答∨

D類音頻功率放大器IC的環路設計

D類音頻功率放大器具有效率高、功耗低的優點,采用D類音頻功率放大器的設備能夠提高電池的壽命,它特別適合應用于無線和手持通信設備,主要應用在PDA、移動電話和類似的手持移動通信工具的設計和產品中。而大功率輸出的音頻設備具有很大 ...…

查看全部問答∨

【MSP430共享】基于MSP430的便攜式醫療監護系統的設計

關于建立醫療監護系統的設計 對于想對提高醫療水平的可以看看…

查看全部問答∨

華為FPGA設計流程指南

華為FPGA設計流程指南…

查看全部問答∨

Vishay 新型電子元器件在工業及新能源中的應用(ZT)

    在光伏逆變器和風電變流器中,威世DC-link薄膜電容可用作穩壓濾波,預期壽命大于15年,具有更低的損耗,更好的穩定性。用4~6薄膜電容MKP1848/9就能替換掉采用60~80個電解電容器的老式設計。101/102 PHR-ST是采用非固態電解液 ...…

查看全部問答∨

一種簡單高效的RFID防沖突算法

無線射頻識別(RFID)是一種非接觸式的自動識別技術,其基本原理是刺用射頻信號和空間耦合(電感或電磁耦合)的傳輸特性,實現對特定物體的自動識別。RFID技術可以追溯至第二次世界大戰期間。后來發展應用到鐵路、軍隊的貨物跟蹤甚至寵物識別上。在過去 ...…

查看全部問答∨
小廣播
設計資源 培訓 開發板 精華推薦

最新單片機文章
何立民專欄 單片機及嵌入式寶典

北京航空航天大學教授,20余年來致力于單片機與嵌入式系統推廣工作。

 
EEWorld訂閱號

 
EEWorld服務號

 
汽車開發圈

 
機器人開發圈

電子工程世界版權所有 京ICP證060456號 京ICP備10001474號-1 電信業務審批[2006]字第258號函 京公網安備 11010802033920號 Copyright ? 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
主站蜘蛛池模板: 固安县| 渝北区| 云浮市| 塘沽区| 珠海市| 乌鲁木齐市| 沁源县| 漳浦县| 广东省| 栖霞市| 新丰县| 岳阳市| 嘉黎县| 昌都县| 蓝田县| 武功县| 清原| 翼城县| 乌拉特中旗| 漳浦县| 台安县| 洛宁县| 乐陵市| 漳州市| 偃师市| 兴城市| 喀什市| 崇礼县| 和平区| 静宁县| 白河县| 日照市| 突泉县| 正宁县| 石渠县| 固始县| 环江| 平罗县| 普定县| 光泽县| 西吉县|