女人自慰AV免费观看内涵网,日韩国产剧情在线观看网址,神马电影网特片网,最新一级电影欧美,在线观看亚洲欧美日韩,黄色视频在线播放免费观看,ABO涨奶期羡澄,第一导航fulione,美女主播操b

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

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

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

第十三章 W55MH32 UPnP端口轉(zhuǎn)發(fā)示例

W55MH32 ? 來源:W55MH32 ? 作者:W55MH32 ? 2025-07-24 10:28 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

單芯片解決方案,開啟全新體驗——W55MH32 高性能以太網(wǎng)單片機

W55MH32是WIZnet重磅推出的高性能以太網(wǎng)單片機,它為用戶帶來前所未有的集成化體驗。這顆芯片將強大的組件集于一身,具體來說,一顆W55MH32內(nèi)置高性能Arm? Cortex-M3核心,其主頻最高可達216MHz;配備1024KB FLASH與96KB SRAM,滿足存儲與數(shù)據(jù)處理需求;集成TOE引擎,包含WIZnet全硬件TCP/IP協(xié)議棧、內(nèi)置MAC以及PHY,擁有獨立的32KB以太網(wǎng)收發(fā)緩存,可供8個獨立硬件socket使用。如此配置,真正實現(xiàn)了All-in-One解決方案,為開發(fā)者提供極大便利。

在封裝規(guī)格上,W55MH32提供了兩種選擇:QFN100和QFN68。

W55MH32L采用QFN100封裝版本,尺寸為12x12mm,其資源豐富,專為各種復雜工控場景設計。它擁有66個GPIO、3個ADC、12通道DMA、17個定時器、2個I2C、5個串口、2個SPI接口(其中1個帶I2S接口復用)、1個CAN、1個USB2.0以及1個SDIO接口。如此豐富的外設資源,能夠輕松應對工業(yè)控制中多樣化的連接需求,無論是與各類傳感器、執(zhí)行器的通信,還是對復雜工業(yè)協(xié)議的支持,都能游刃有余,成為復雜工控領域的理想選擇。同系列還有QFN68封裝的W55MH32Q版本,該版本體積更小,僅為8x8mm,成本低,適合集成度高的網(wǎng)關模組等場景,軟件使用方法一致。更多信息和資料請進入http://www.w5500.com/網(wǎng)站或者私信獲取。

此外,本W(wǎng)55MH32支持硬件加密算法單元,WIZnet還推出TOE+SSL應用,涵蓋TCP SSL、HTTP SSL以及 MQTT SSL等,為網(wǎng)絡通信安全再添保障。

為助力開發(fā)者快速上手與深入開發(fā),基于W55MH32L這顆芯片,WIZnet精心打造了配套開發(fā)板。開發(fā)板集成WIZ-Link芯片,借助一根USB C口數(shù)據(jù)線,就能輕松實現(xiàn)調(diào)試、下載以及串口打印日志等功能。開發(fā)板將所有外設全部引出,拓展功能也大幅提升,便于開發(fā)者全面評估芯片性能。

若您想獲取芯片和開發(fā)板的更多詳細信息,包括產(chǎn)品特性、技術參數(shù)以及價格等,歡迎訪問官方網(wǎng)頁:http://www.w5500.com/,我們期待與您共同探索W55MH32的無限可能。

wKgZO2iBiBmAe3DyAACpGc5mWX8613.png

第十三章 W55MH32 UPnP端口轉(zhuǎn)發(fā)示例

本篇文章,我們將詳細介紹如何在W55MH32芯片上面實現(xiàn)UPnP協(xié)議。使用W55MH32的TOE引擎,我們只需進行簡單的socket編程寄存器讀寫,便可輕松實現(xiàn)以太網(wǎng)應用。接下來我們通過實戰(zhàn)例程,為大家講解如何使用TOE引擎實現(xiàn)UPnP協(xié)議的端口轉(zhuǎn)發(fā)功能。

該例程用到的其他網(wǎng)絡協(xié)議,例如DHCP,請參考相關章節(jié)。有關W55MH32的初始化過程,請參考Network Install章節(jié),這里將不再贅述。

1 UPnP協(xié)議簡介

UPnP(Universal Plug and Play)協(xié)議是一種支持設備在局域網(wǎng)中實現(xiàn)自動發(fā)現(xiàn)和通信的網(wǎng)絡協(xié)議。其端口轉(zhuǎn)發(fā)功能由IGD Profile提供,允許局域網(wǎng)設備動態(tài)請求路由器為其開放指定的端口,以實現(xiàn)外部設備訪問內(nèi)部服務。這種功能消除了手動配置端口轉(zhuǎn)發(fā)的復雜性,特別適用于需要穿透NAT(網(wǎng)絡地址轉(zhuǎn)換)環(huán)境的應用場景。

IGDInternet Gateway Device,互聯(lián)網(wǎng)網(wǎng)關設備)是UPnP(Universal Plug and Play)協(xié)議的一部分,主要用于管理網(wǎng)絡中的網(wǎng)關設備(如路由器)的服務和資源。IGD擴展定義了一套標準接口,允許局域網(wǎng)設備與網(wǎng)關設備通信,動態(tài)配置網(wǎng)絡設置,例如端口轉(zhuǎn)發(fā)、帶寬管理和連接狀態(tài)查詢等。

2 UPnP協(xié)議特點

自動化配置:無需用戶手動設置,減少了配置錯誤的風險。

動態(tài)靈活:端口映射規(guī)則可以根據(jù)需求動態(tài)添加或刪除。

設備友好:支持即插即用,簡化了設備的聯(lián)網(wǎng)和部署過程。

跨設備兼容:UPnP基于標準化協(xié)議,廣泛支持各種設備和平臺。

3 UPnP應用場景

通過UPnP端口轉(zhuǎn)發(fā)功能,我們可以使用W55MH32實現(xiàn)以下功能:

遠程訪問:將外部請求轉(zhuǎn)發(fā)到局域網(wǎng)設備(如NAS、監(jiān)控攝像頭),實現(xiàn)外部遠程訪問內(nèi)部設備。

遠程控制:外部設備通過UPnP轉(zhuǎn)換的端口,可以實現(xiàn)遠程控制局域網(wǎng)內(nèi)部設備(智能門鎖、燈光控制器)。

4 UPnP設置端口轉(zhuǎn)發(fā)的工作流程

設備發(fā)現(xiàn):W55MH32通過SSDP(Simple Service Discovery Protocol)向局域網(wǎng)中發(fā)送組播請求(HTTP M-SEARCH報文),搜索支持IGD的網(wǎng)關設備。

獲取服務描述:W55MH32訪問網(wǎng)關設備(路由器)獲取服務描述文件,了解支持的服務和接口。

訂閱IGD事件:通過事件訂閱,W55MH32可以在不主動輪詢的情況下,接收實時通知。

調(diào)用服務接口:使用UPnP的SOAT消息調(diào)用IGD提供的端口映射接口。

數(shù)據(jù)交互測試:外部通過訪問映射的端口及路由器地址和局域網(wǎng)內(nèi)部設備進行通信。

5報文講解

設備搜索

上文我們提到,設備搜索時使用SSDP協(xié)議,SSDP(Simple Service Discovery Protocol)是 UPnP協(xié)議中的關鍵協(xié)議,用于設備發(fā)現(xiàn)和服務發(fā)布。它通過HTTP over UDP的形式在局域網(wǎng)內(nèi)廣播和接收報文,采用多播地址 239.255.255.250和端口 1900。

SSDP報文主要分為以下幾類:

NOTIFY消息(設備主動廣播通知):用于設備向網(wǎng)絡通告自己的存在或離線狀態(tài)。

M-SEARCH消息(客戶端主動搜索):客戶端發(fā)送搜索請求以發(fā)現(xiàn)設備或服務。

HTTP/1.1響應消息(設備對 M-SEARCH的響應):設備對搜索請求的響應,提供設備描述文件的位置及服務信息。

SSDP報文基于HTTP協(xié)議,有固定的格式,主要包括以下字段:

HOST:目標地址和端口,固定為 239.255.255.250:1900。

MAN:用于標識搜索消息,固定為 "ssdp:discover"(僅在 M-SEARCH中使用)。

MX:最大響應時間,指定設備在多長時間內(nèi)響應(單位:秒)。

ST:搜索目標,標識要查找的設備類型或服務類型。

NT:通知類型,表示設備或服務的類型(在 NOTIFY消息中使用)。

USN:唯一服務名稱,設備或服務的唯一標識符。

LOCATION:設備描述文件的 URL,包含設備的詳細信息。

CACHE-CONTROL:設備信息的緩存時間,表示在多長時間內(nèi)有效。

M-SEARCH請求報文實例:

M-SEARCH * HTTP/1.1
Host:239.255.255.250:1900
ST:urn:schemas-upnp-org:device:InternetGatewayDevice:1
Man:"ssdp:discover"
MX:3

字段解析:

M-SEARCH * HTTP/1.1:表明是一個搜索請求。

Host:多播地址和端口。

ST:搜索目標類型,這里是IGD設備。

MX:最大響應事件,設備需要在3秒內(nèi)返回響應。

Man:搜索請求類型,固定。

M-SEARCH響應報文實例:

HTTP/1.1 200 OK
CACHE-CONTROL: max-age=60
DATE: Tue, 07 Jan 2025 06:43:49 GMT
EXT:
LOCATION: http://192.168.100.1:1900/igd.xml
SERVER: vxWorks/5.5 UPnP/1.0 TL-WR886N/6.0
ST: urn:schemas-upnp-org:device:InternetGatewayDevice:1
USN: uuid:8c15e41f-3d83-41c1-b35d-5D2A64377DE9::urn:schemas-upnp-org:device:InternetGatewayDevice:1

HTTP/1.1 200 OK:表示響應成功。

CACHE-CONTROL:響應有效時間為60秒。

DATE:響應的時間戳。

EXT:保留字段,目前為空。

LOCATION:設備描述文件的URL。

SERVER:設備的操作系統(tǒng),UPnP版本和設備名稱。

ST:搜索目標類型,和請求中的ST字段一致。

USN:唯一設備標識符。

獲取設備標識符

這一步會通過HTTP GET方式去請求xml文件,有關HTTP GET報文以及HTTP響應報文這里不過多講解,有興趣的可以參考 HTTP Client章節(jié)。

請求示例:

GET /igd.xml HTTP/1.1
Accept: text/xml, application/xml
User-Agent: Mozilla/4.0 (compatible; UPnP/1.0; Windows NT/5.1)
Host: 192.168.100.1:1900
Connection: Keep-Alive
Cache-Control: no-cache
Pragma: no-cache

響應示例:

HTTP/1.1 200 OK
Content-Type: text/xml;charset=UTF-8
Content-Length: 2580
Connection: close
Cache-control: no-cache




1
0


urn:schemas-upnp-org:device:InternetGatewayDevice:1
http://192.168.100.1:80 
Wireless N Router TL-WR886N
TP-LINK
http://www.tp-link.com.cn
TL-WR886N 6.0
TL-WR886N
6.0
uuid:8c15e41f-3d83-41c1-b35d-5D2A64377DE9
123456789001


urn:schemas-upnp-org:service:Layer3Forwarding:1
urn:upnp-org:serviceId:L3Forwarding1
/l3f
/l3f
/l3f.xml




urn:schemas-upnp-org:device:WANDevice:1
WAN Device
TP-LINK
http://www.tp-link.com.cn
WAN Device
WAN Device
1.0

12345678900001
uuid:8c15e41f-3d83-41c1-b35d-5D2A64377DE9
123456789001


urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1
urn:upnp-org:serviceId:WANCommonInterfaceConfig
/ifc
/ifc
/ifc.xml




urn:schemas-upnp-org:device:WANConnectionDevice:1
WAN Connection Device
TP-LINK
http://www.tp-link.com.cn
WAN Connection Device
WAN Connection Device
1.0

12345678900001
uuid:8c15e41f-3d83-41c1-b35d-5D2A64377DE9
123456789001


urn:schemas-upnp-org:service:WANIPConnection:1
urn:upnp-org:serviceId:WANIPConnection
/ipc
/ipc
/ipc.xml







訂閱IGD事件

通過HTTP SUBSCRIBE訂閱IGD事件,示例:

SUBSCRIBE /ipc HTTP/1.1
Host: 192.168.100.1:1900
USER-AGENT: Mozilla/4.0 (compatible; UPnP/1.1; Windows NT/5.1)
CALLBACK: 
NT: upnp:event
TIMEOUT: Second-1800

響應示例:

HTTP/1.1 200 OK
Content-Type: text/xml;charset=UTF-8
Content-Length: 0
Connection: close
Cache-control: no-cache
Server: vxWorks/5.5 UPnP/1.0 TL-WR886N/6.0
Timeout: Second-1800
SID: uuid:82-2150160019

添加映射端口報文

例如,我們想映射TCP協(xié)議的內(nèi)部端口8000到外部端口1000上,可以按照以下示例進行HTTP請求:

POST /ipc HTTP/1.1
Content-Type: text/xml; charset="utf-8"
SOAPAction: "urn:schemas-upnp-org:service:WANIPConnection:1#AddPortMapping"
User-Agent: Mozilla/4.0 (compatible; UPnP/1.0; Windows NT/5.1)
Host: 192.168.100.1:1900
Content-Length: 1131
Connection: Keep-Alive
Cache-Control: no-cache
Pragma: no-cache








1000

TCP

8000

192.168.100.101
1
W5500_uPnPGetway
0


主要字段的描述如下:

m:AddPortMapping:添加端口映射

NewExternalPort:外部端口號

NewProtocol:協(xié)議類型

NewInternalPort:內(nèi)部端口號

NewInternalClient:內(nèi)部地址

響應內(nèi)容:

HTTP/1.1 200 OK
Content-Type: text/xml;charset=UTF-8
Content-Length: 289
Connection: close
Cache-control: no-cache
Server: vxWorks/5.5 UPnP/1.0 TL-WR886N/6.0


刪除端口映射報文

例如,我們想刪除上面映射的1000端口,可以按照以下示例進行HTTP請求:

POST /ipc HTTP/1.1
Content-Type: text/xml; charset="utf-8"
SOAPAction: "urn:schemas-upnp-org:service:WANIPConnection:1#DeletePortMapping"
User-Agent: Mozilla/4.0 (compatible; UPnP/1.0; Windows NT/5.1)
Host: 192.168.100.1:1900
Content-Length: 604
Connection: Keep-Alive
Cache-Control: no-cache
Pragma: no-cache





1000
TCP

主要字段的描述如下:

m:DeletePortMapping:刪除端口映射

NewExternalPort:外部端口號

NewProtocol:協(xié)議類型

NewRemoteHost:外部訪問來源,可以為空

6實現(xiàn)過程

在這個例程中,我們實現(xiàn)了通過串口控制LED燈開關、獲取和設置網(wǎng)絡地址信息、TCP和UDP回環(huán)數(shù)據(jù)測試以及UPnP添加映射端口和刪除映射端口的功能。

注意:測試實例需要W55MH32接入在支持UPnP端口轉(zhuǎn)發(fā)的路由器下。

步驟1:設置以太網(wǎng)緩存大小

static uint8_t  tx_size[_WIZCHIP_SOCK_NUM_] = {4, 4, 2, 1, 1, 1, 1, 2};
static uint8_t  rx_size[_WIZCHIP_SOCK_NUM_] = {4, 4, 2, 1, 1, 1, 1, 2};
/* socket rx and tx buff init */
wizchip_init(tx_size, rx_size);

在這里我們給socket0-7的收發(fā)緩存分別設置為4KB,4KB,2KB,1KB,1KB,1KB,1KB,2KB。

其中socket0用于UPnP協(xié)議處理,socket1用于TCP和UDP回環(huán)處理,socket2用于監(jiān)聽IGD事件。

步驟2:LED控制函數(shù)注冊

UserLED_Control_Init(set_user_led_status);

set_user_led_status()函數(shù)為控制LED的函數(shù),具體內(nèi)容如下:

/*void set_user_led_status(uint8_t val)
{
 if (val)
 {
     GPIO_SetBits(GPIOD, GPIO_Pin_14);
 }
 else
 {
     GPIO_ResetBits(GPIOD, GPIO_Pin_14);
 }
}

步驟3:搜索UPnP設備

do
{
   printf("Send SSDP.. rn");
}   while (SSDPProcess(SOCKET_ID) != 0); // SSDP Search discovery

/**< SSDP Header */
unsigned char SSDP[] = "
M-SEARCH * HTTP/1.1rn
Host:239.255.255.250:1900rn
ST:urn:schemas-upnp-org:device:InternetGatewayDevice:1rn
Man:"ssdp:discover"rn
MX:3rn
rn
";
/**
* @brief This function processes the SSDP message.
* @return 0: success, -1: reply packet timeout, 1: received SSDP parse error
*/
signed char SSDPProcess(SOCKET sockfd)
{
 char          ret_value     = 0;
 long          endTime       = 0;
 unsigned char mcast_addr[4] = {239, 255, 255, 250};
 // unsigned char_t_t mcast_mac[6] = {0x28, 0x2C, 0xB2, 0xE9, 0x42, 0xD6};
 unsigned char  recv_addr[4];
 unsigned short recv_port;
 // UDP Socket Open
 close(sockfd);
 socket(sockfd, Sn_MR_UDP, PORT_SSDP, 0); /*Initialize socket for socket 0*/
 while (getSn_SR(sockfd) != SOCK_UDP);
#ifdef UPNP_DEBUG
 printf("%srn", SSDP);
#endif
 // Send SSDP
 if (sendto(sockfd, SSDP, strlen((char *)SSDP), mcast_addr, 1900) <= 0)
     printf("SSDP Send error!!!!!!!rn");
 // Receive Reply
 memset(recv_buffer, '', RECV_BUFFER_SIZE);
 endTime = my_time + 3;
 while (recvfrom(sockfd, (unsigned char *)recv_buffer, RECV_BUFFER_SIZE, recv_addr, &recv_port) <= 0 && my_time < endTime); // Check Receive Buffer
 if (my_time >= endTime)
 {                                                                                                                          // Check Timeout
     close(sockfd);
     return -1;
 }
 // UDP Socket Close
 close(sockfd);
#ifdef UPNP_DEBUG
 printf("rnReceiveDatarn%srn", recv_buffer);
#endif
 // Parse SSDP Message
 if ((ret_value = parseSSDP(recv_buffer)) == 0)
     UPnP_Step = 1;
 return ret_value;
}

在這個函數(shù)中,主要是使用SSDP協(xié)議搜索IGD設備,發(fā)送報文和前面我們介紹的一致。

步驟4:獲取IGD設備描述

if (GetDescriptionProcess(SOCKET_ID) == 0) // GET IGD description
{
   printf("GetDescription Success!!rn");
}
else
{
   printf("GetDescription Fail!!rn");
}

/**
* @brief This function gets the description message from IGD(Internet Gateway Device).
* @return 0: success, -2: Invalid UPnP Step, -1: reply packet timeout, 1: received xml parse error
*/
signed char GetDescriptionProcess(
SOCKET sockfd /**< a socket number. */
)
{
char           ret_value = 0;
long           endTime   = 0;
unsigned long  ipaddr;
unsigned short port;
// Check UPnP Step
if (UPnP_Step < 1) return -2;
// Make HTTP GET Header
memset(send_buffer, '', SEND_BUFFER_SIZE);
MakeGETHeader(send_buffer);
#ifdef UPNP_DEBUG
printf("%srn", send_buffer);
#endif
ipaddr = inet_addr((unsigned char *)descIP);
ipaddr = swapl(ipaddr);
port   = ATOI(descPORT, 10);
// Connect to IGD(Internet Gateway Device)
close(sockfd);
socket(sockfd, Sn_MR_TCP, PORT_UPNP, Sn_MR_ND); /*Open a port of the socket*/
while (getSn_SR(sockfd) != SOCK_INIT)
{
 delay_ms(100);
}
if (connect(sockfd, (unsigned char *)&ipaddr, port) == 0)
 printf("TCP Socket Error!!rn");
// Send Get Discription Message
while ((getSn_SR(sockfd) != SOCK_ESTABLISHED));
send(sockfd, (void *)send_buffer, strlen(send_buffer));
// Receive Reply
memset(recv_buffer, '', RECV_BUFFER_SIZE);
delay_ms(500);
endTime = my_time + 3;
while (recv(sockfd, (void *)recv_buffer, RECV_BUFFER_SIZE) <= 0 && my_time < endTime); // Check Receive Buffer
if (my_time >= endTime)
{                                                                                      // Check Timeout
 close(sockfd);
 return -1;
}
// TCP Socket Close
close(sockfd);
#ifdef UPNP_DEBUG
printf("rnReceiveDatarn%srn", recv_buffer);
#endif
// Parse Discription Message
if ((ret_value = parseDescription(recv_buffer)) == 0) UPnP_Step = 2;
return ret_value;
}

請求報文通過MakeGETHeader()函數(shù)進行組包,具體報文如下:

/**
* @brief   This function makes the HTTP GET header.
* @param   dest:Target string pointer
* @return  none
*/
void MakeGETHeader(char *dest)
{
   char local_port[6] = {''};
   strcat(dest, "GET ");
   strcat(dest, descLOCATION);
   strcat(dest, " HTTP/1.1rn");
   strcat(dest, "Accept: text/xml, application/xmlrn");
   strcat(dest, "User-Agent: Mozilla/4.0 (compatible; UPnP/1.0; Windows NT/5.1)rn");
   strcat(dest, "Host: ");
   strcat(dest, descIP);
   sprintf(local_port, ":%s", descPORT);
   strcat(dest, local_port);
   strcat(dest, "rnConnection: Keep-AlivernCache-Control: no-cachernPragma: no-cachernrn");
}

然后將接收到的內(nèi)容,通過parseDescription()函數(shù)進行解析,如果設備描述中不支持WANIPConnection服務,則說明不支持端口映射,返回錯誤。

parseDescription()函數(shù)內(nèi)容如下:

/**
* @brief This function parses the received description message from IGD(Internet Gateway Dev
* @return 0: success, 1: received xml parse error
*/
signed char parseDescription(
   const char *xml /**< string for parse */
)
{
   const char controlURL_[]  = "";
   const char eventSubURL_[] = "";
   char      *URL_start = 0, *URL_end = 0;
   if (parseHTTP(xml) != 0) return 1;
   //printf("rn%srn", xml);
   // Find Control URL("/etc/linuxigd/gateconnSCPD.ctl")
   if ((URL_start = strstr(xml, "urn:schemas-upnp-org:service:WANIPConnection:1")) == NULL) retur
   if ((URL_start = strstr(URL_start, controlURL_)) == NULL) return 1;
   if ((URL_end = strstr(URL_start, "")) == NULL) return 1;
   strncpy(controlURL, URL_start + strlen(controlURL_), URL_end - URL_start - strlen(controlURL_)
   // Find Eventing Subscription URL("/etc/linuxigd/gateconnSCPD.evt")
   if ((URL_start = strstr(xml, "urn:schemas-upnp-org:service:WANIPConnection:1")) == NULL) retur
   if ((URL_start = strstr(URL_start, eventSubURL_)) == NULL) return 1;
   if ((URL_end = strstr(URL_start, "")) == NULL) return 1;
   strncpy(eventSubURL, URL_start + strlen(eventSubURL_), URL_end - URL_start - strlen(eventSubUR
   return 0;
}

步驟5:訂閱IGD事件

if (SetEventing(SOCKET_ID) == 0) // Subscribes IGD event messages
{
   printf("SetEventing Success!!rn");
}
else
{
   printf("SetEventing Fail!!rn");
}

SetEventing()函數(shù)內(nèi)容如下:

/**
* @brief This function subscribes to the eventing message from IGD(Internet Gateway Device).
* @return 0: success, -2: Invalid UPnP Step, -1: reply packet timeout
*/
signed char SetEventing(
 SOCKET sockfd /**< a socket number. */
)
{
 long           endTime = 0;
 unsigned long  ipaddr;
 unsigned short port;
 // Check UPnP Step
 if (UPnP_Step < 2) return -2;
 // Make Subscription message
 memset(send_buffer, '', SEND_BUFFER_SIZE);
 MakeSubscribe(send_buffer, PORT_UPNP_EVENTING);
#ifdef UPNP_DEBUG
 printf("%srn", send_buffer);
#endif
 ipaddr = inet_addr((unsigned char *)descIP);
 ipaddr = swapl(ipaddr);
 port   = ATOI(descPORT, 10);
 // Connect to IGD(Internet Gateway Device)
 close(sockfd);
 socket(sockfd, Sn_MR_TCP, PORT_UPNP, Sn_MR_ND); /*Open a port of the socket*/
 while (getSn_SR(sockfd) != SOCK_INIT)
 {
     delay_ms(100);
 }
 if (connect(sockfd, (unsigned char *)&ipaddr, port) == 0)
     printf("TCP Socket Error!!rn");
 // Send Get Discription Message
 while ((getSn_SR(sockfd) != SOCK_ESTABLISHED));
 send(sockfd, (void *)send_buffer, strlen(send_buffer));
 // Receive Reply
 memset(recv_buffer, '', RECV_BUFFER_SIZE);
 delay_ms(500);
 endTime = my_time + 3;
 while (recv(sockfd, (void *)recv_buffer, RECV_BUFFER_SIZE) <= 0 && my_time < endTime); // Check Receive Buffer
 if (my_time >= endTime)
 {                                                                                      // Check Timeout
     close(sockfd);
     return -1;
 }
 // TCP Socket Close
 close(sockfd);
#ifdef UPNP_DEBUG
 printf("rnReceiveDatarn%srn", recv_buffer);
#endif
 return parseHTTP(recv_buffer);
}

請求報文通過MakeSubscribe()函數(shù)進行組包,具體報文如下:

/**
* @brief   This function makes the Subscription message.
* @param   dest:Target string pointer
* @param   listen_port:Listen port
* @return  none
*/
void MakeSubscribe(char *dest, const unsigned int listen_port)
{
   char          local_port[6] = {''}, ipaddr[16] = {''};
   unsigned char ip[4];
   strcat(dest, "SUBSCRIBE ");
   strcat(dest, eventSubURL);
   strcat(dest, " HTTP/1.1rn");
   strcat(dest, "Host: ");
   strcat(dest, descIP);
   sprintf(local_port, ":%s", descPORT);
   strcat(dest, local_port);
   strcat(dest, "rnUSER-AGENT: Mozilla/4.0 (compatible; UPnP/1.1; Windows NT/5.1)rn");
   strcat(dest, "CALLBACK: ", listen_port);
   strcat(dest, local_port);
   strcat(dest, "rnNT: upnp:eventrnTIMEOUT: Second-1800rnrn");
}

最后,通過parseHTTP()函數(shù)解析HTTP響應報文,判斷是否訂閱成功。

parseHTTP()函數(shù)如下:

/*-----String Parse Functions-----*/
/**
 * @brief This function parses the HTTP header.
 * @return 0: success, 1: received xml parse error
 */
signed char parseHTTP(
   const char *xml /**< string for parse */
)
{
   char *loc = 0;
   if (strstr(xml, "200 OK") != NULL)
       return 0;
   else
   {
       loc = strstr(xml, "rn");
       memset(content, '', CONT_BUFFER_SIZE);
       strncpy(content, xml, loc - xml);
       printf("rnHTTP Error:rn%srnrn", content);
       return 1;
   }
}

步驟6:執(zhí)行UPnP主程序

Main_Menu(SOCKET_ID, SOCKET_ID + 1, SOCKET_ID + 2, ethernet_buf, tcps_port, udps_port); // Main menu

/**
* @brief   Display/Manage a Menu on HyperTerminal Window
* @param   sn: use for SSDP; sn2: use for run tcp/udp loopback; sn3: use for listenes IGD event message
* @param   buf: use for tcp/udp loopback rx/tx buff; tcps_port: use for tcp loopback listen; udps_port: use 
for udp loopback receive
* @return  none
*/
void Main_Menu(uint8_t sn, uint8_t sn2, uint8_t sn3, uint8_t *buf, uint16_t tcps_port, uint16_t udps_port)
{
   static char           choice[3];
   static char           msg[256], ipaddr[12], protocol[4];
   static unsigned short ret, external_port, internal_port;
   static uint8_t        bTreat;
   static uint8_t        Sip[4];
   while (1)
   {
       /* Display Menu on HyperTerminal Window */
       bTreat = RESET;
       printf("rn====================== WIZnet Chip Control Point ===================rn");
       printf("This Application is basic example of UART interface withrn");
       printf("Windows Hyper Terminal. rn");
       printf("rn==========================================================rn");
       printf("                          APPLICATION MENU :rn");
       printf("rn==========================================================rnn");
       printf(" 1 - Set LED on rn");
       printf(" 2 - Set LED off rn");
       printf(" 3 - Show network settingrn");
       printf(" 4 - Set  network settingrn");
       printf(" 5 - Run TCP Loopbackrn");
       printf(" 6 - Run UDP Loopbackrn");
       printf(" 7 - UPnP PortForwarding: AddPortrn");
       printf(" 8 - UPnP PortForwarding: DeletePortrn");
       printf("Enter your choice : ");
       memset(choice, 0, sizeof(choice));
       scanf("%s", choice);
       printf("%crn", choice[0]);

在這里會執(zhí)行一個用戶選項菜單,選項1和2控制LED開關,選項3和4打印和設置網(wǎng)絡地址信息,選項5運行一個TCP回環(huán)測試程序(回環(huán)測試程序可參考TCP Server章節(jié)),選項6運行一個UDP回環(huán)測試程序(回環(huán)測試程序可參考UDP章節(jié))。選項7添加一個UPnP端口映射表,選項8刪除一個UPnP端口映射表。這里我們主要講解UPnP相關的選項7和選項8。

步驟7:添加一個UPnP端口映射表

代碼如下:

if (choice[0] == '7')
{
 bTreat = SET;
 printf("rnType a Protocol(TCP/UDP) : ");
 memset(msg, 0, sizeof(msg));
 scanf("%s", msg);
 printf("%srn", msg);
 strncpy(protocol, msg, 3);
 protocol[3] = '';
 printf("rnType a External Port Number : ");
 memset(msg, 0, sizeof(msg));
 scanf("%s", msg);
 printf("%srn", msg);
 external_port = ATOI(msg, 10);
 printf("rnType a Internal Port Number : ");
 memset(msg, 0, sizeof(msg));
 scanf("%s", msg);
 printf("%srn", msg);
 internal_port = ATOI(msg, 10);
 if(strcmp(protocol,"tcp") || strcmp(protocol,"TCP"))
     tcps_port     = internal_port;
 else
     udps_port     = internal_port;
 close(sn2);
 // Try to Add Port Action
 getSIPR(Sip);
 sprintf(ipaddr, "%d.%d.%d.%d", Sip[0], Sip[1], Sip[2], Sip[3]);
 if ((ret = AddPortProcess(sn, protocol, external_port, ipaddr, internal_port, "W5500_uPnPGetway")) == 0)
     printf("AddPort Success!!rn");
 else
     printf("AddPort Error Code is %drn", ret);
}

在這里,我們需要外部輸入端口映射的協(xié)議類型(TCP或UDP),以及外部端口號和內(nèi)部端口號。輸入完成后,選項5或選項6的端口號會替換為輸入的內(nèi)部端口號,然后通過AddPortProcess()函數(shù)執(zhí)行添加端口映射處理。AddPortProcess()函數(shù)內(nèi)容如下:

/**
* @brief This function processes the add port to IGD(Internet Gateway Device).
* @return 0: success, -2: Invalid UPnP Step, -1: reply packet timeout, 1: received xml parse error, other: UPnP error code
*/
signed short AddPortProcess(
SOCKET             sockfd,         /**< a socket number. */
const char        *protocol,       /**< a procotol name. "TCP" or "UDP" */
const unsigned int extertnal_port, /**< an external port number. */
const char        *internal_ip,    /**< an internal ip address. */
const unsigned int internal_port,  /**< an internal port number. */
const char        *description     /**< a description of this portforward. */
)
{
 short          len     = 0;
 long           endTime = 0;
 unsigned long  ipaddr;
 unsigned short port;
 // Check UPnP Step
 if (UPnP_Step < 2) return -2;
 // Make "Add Port" XML(SOAP)
 memset(content, '', CONT_BUFFER_SIZE);
 MakeSOAPAddControl(content, protocol, extertnal_port, internal_ip, internal_port, description);
 // Make HTTP POST Header
 memset(send_buffer, '', SEND_BUFFER_SIZE);
 len = strlen(content);
 MakePOSTHeader(send_buffer, len, ADD_PORT);
 strcat(send_buffer, content);
 //#ifdef UPNP_DEBUG
 printf("%srn", send_buffer);
 //#endif
 ipaddr = inet_addr((unsigned char *)descIP);
 ipaddr = swapl(ipaddr);
 port   = ATOI(descPORT, 10);
 // Connect to IGD(Internet Gateway Device)
 socket(sockfd, Sn_MR_TCP, PORT_UPNP, Sn_MR_ND); /*Open a port of the socket*/
 while (getSn_SR(sockfd) != SOCK_INIT);
 if (connect(sockfd, (unsigned char *)&ipaddr, port) == 0)
     printf("TCP Socket Error!!rn");
 // Send "Delete Port" Message
 while (getSn_SR(sockfd) != SOCK_ESTABLISHED);
 send(sockfd, (void *)send_buffer, strlen(send_buffer));
 // Receive Reply
 memset(recv_buffer, '', RECV_BUFFER_SIZE);
 delay_ms(500);
 endTime = my_time + 3;
 while (recv(sockfd, (void *)recv_buffer, RECV_BUFFER_SIZE) <= 0 && my_time < endTime); // Check Receive Buffer
 if (my_time >= endTime)
 {                                                                                      // Check Timeout
     close(sockfd);
     return -1;
 }
 // TCP Socket Close
 close(sockfd);
 //#ifdef UPNP_DEBUG
 printf("rnReceiveDatarn%srn", recv_buffer);
 //#endif
 // Parse Replied Message
 return parseAddPort(recv_buffer);
}

程序首先會通過MakeSOAPAddControl()函數(shù)組裝請求報文中的XML部分,具體內(nèi)容如下:

/**< SOAP header & tail */
const char soap_start[] =
   "
rn

";
const char soap_end[] =
   "
rn
";
/**< Delete Port Mapping */
const char DeletePortMapping_[] = "";
const char _DeletePortMapping[] = "";
/**< New Remote Host */
const char NewRemoteHost_[] = "";
const char _NewRemoteHost[] = "";
/**< New External Port */
const char NewExternalPort_[] = "";
const char _NewExternalPort[] = "";
/**< New Protocol */
const char NewProtocol_[] = "";
const char _NewProtocol[] = "";
/**< Add Port Mapping */
const char AddPortMapping_[] = "";
const char _AddPortMapping[] = "";
/**< New Internal Port */
const char NewInternalPort_[] = "";
const char _NewInternalPort[] = "";
/**< New Internal Client */
const char NewInternalClient_[] = "";
const char _NewInternalClient[] = "";
/**< New Enabled */
const char NewEnabled[]  = "1";
const char NewEnabled_[] = "";
const char _NewEnabled[] = "";
/**< New Port Mapping Description */
const char NewPortMappingDescription_[] = "";
const char _NewPortMappingDescription[] = "";
/**< New Lease Duration */
const char NewLeaseDuration[]  = "0";
const char NewLeaseDuration_[] = "";
const char _NewLeaseDuration[] = "";
/**
* @brief   This function makes the Add Port Control message in SOAP.
* @param   dest:Target string pointer
* @param   protocol:Protocol type
* @param   extertnal_port:External port
* @param   internal_ip:Internal IP address
* @param   internal_port:Internal port
* @param   description:Description
* @return  none
*/
void MakeSOAPAddControl(char *dest, const char *protocol, const unsigned int extertnal_port, const char * internal_ip, const unsigned int internal_port, const char *description)
{
   char local_port[6] = {''};
   strcat(dest, soap_start);
   strcat(dest, AddPortMapping_);
   strcat(dest, NewRemoteHost_);
   strcat(dest, _NewRemoteHost);
   strcat(dest, NewExternalPort_);
   sprintf(local_port, "%d", extertnal_port);
   strcat(dest, local_port);
   strcat(dest, _NewExternalPort);
   strcat(dest, NewProtocol_);
   strcat(dest, protocol);
   strcat(dest, _NewProtocol);
   strcat(dest, NewInternalPort_);
   sprintf(local_port, "%d", internal_port);
   strcat(dest, local_port);
   strcat(dest, _NewInternalPort);
   strcat(dest, NewInternalClient_);
   strcat(dest, internal_ip);
   strcat(dest, _NewInternalClient);
   strcat(dest, NewEnabled);
   strcat(dest, NewPortMappingDescription_);
   strcat(dest, description);
   strcat(dest, _NewPortMappingDescription);
   strcat(dest, NewLeaseDuration);
   strcat(dest, _AddPortMapping);
   strcat(dest, soap_end);
}

然后通過MakePOSTHeader()函數(shù)制作HTTP頭部內(nèi)容,具體內(nèi)容如下:

  /**
 * @brief   This function makes the HTTP POST Header.
 * @param   dest:Target string pointer
 * @param   content_length: content length
 * @param   action: action type
 * @return  none
 */
 void MakePOSTHeader(char *dest, int content_length, int action)
 {
     char local_length[6] = {''}, local_port[6] = {''};
     sprintf(local_length, "%d", content_length);
     strcat(dest, "POST ");
     strcat(dest, controlURL);
     strcat(dest, " HTTP/1.1rn");
     strcat(dest, "Content-Type: text/xml; charset="utf-8"rn");
     strcat(dest, "SOAPAction: "urn:schemas-upnp-org:service:WANIPConnection:1#");
     switch (action)
     {
     case DELETE_PORT:
         strcat(dest, "DeletePortMapping"");
         break;
     case ADD_PORT:
         strcat(dest, "AddPortMapping"");
         break;
     }
     strcat(dest, "rnUser-Agent: Mozilla/4.0 (compatible; UPnP/1.0; Windows NT/5.1)rn");
     strcat(dest, "Host: ");
     strcat(dest, descIP);
     sprintf(local_port, ":%s", descPORT);
     strcat(dest, local_port);
     strcat(dest, "rnContent-Length: ");
     strcat(dest, local_length);
     strcat(dest, "rnConnection: Keep-AlivernCache-Control: no-cachernPragma: no-cachernrn");
 }

最后則是發(fā)送請求,然后通過parseAddPort()函數(shù)解析響應內(nèi)容判斷是否添加端口映射成功。

signed short parseAddPort(
 const char *xml /**< string for parse */
)
{
 parseHTTP(xml);
 if (strstr(xml, "u:AddPortMappingResponse xmlns:u="urn:schemas-upnp-org:service:WANIPConnection:1"") == NULL)
 {
     return parseError(xml);
 }
 return 0;
}

步驟8:刪除一個UPnP端口映射表

if (choice[0] == '8')
{
 bTreat = SET;
 printf("rnType a Protocol(TCP/UDP) : ");
 memset(msg, 0, sizeof(msg));
 scanf("%s", msg);
 printf("%srn", msg);
 //GetInputString(msg);
 strncpy(protocol, msg, 3);
 protocol[3] = '';
 printf("rnType a External Port Number : ");
 //   TCP_LISTEN_PORT=num;
 //   UDP_LISTEN_PORT=num;
 //   printf("%drn",TCP_LISTEN_PORT);
 memset(msg, 0, sizeof(msg));
 scanf("%s", msg);
 printf("%srn", msg);
 external_port = ATOI(msg, 10);
 // Try to Delete Port Action
 if ((ret = DeletePortProcess(sn, protocol, external_port)) == 0)
     printf("DeletePort Success!!rn");
 else
     printf("DeletePort Error Code is %drn", ret);
}
/* OTHERS CHOICE*/
if (bTreat == RESET)
{
 printf(" wrong choice  rn");
}

在這里,我們需要外部輸入刪除端口映射的協(xié)議類型(TCP或UDP),以及外部端口號。輸入完成后,通過DeletePortProcess()函數(shù)執(zhí)行添加端口映射處理。DeletePortProcess()函數(shù)內(nèi)容如下:

/**
* @brief This function processes the delete port to IGD(Internet Gateway Device).
* @return 0: success, -2: Invalid UPnP Step, -1: reply packet timeout, 1: received xml parse error, other: UPnP error code
*/
signed short DeletePortProcess(
 SOCKET             sockfd,        /**< a socket number. */
 const char        *protocol,      /**< a procotol name. "TCP" or "UDP" */
 const unsigned int extertnal_port /**< an external port number. */
)
{
 short          len     = 0;
 long           endTime = 0;
 unsigned long  ipaddr;
 unsigned short port;
 // Check UPnP Step
 if (UPnP_Step < 2) return -2;
 // Make "Delete Port" XML(SOAP)
 memset(content, '', CONT_BUFFER_SIZE);
 MakeSOAPDeleteControl(content, protocol, extertnal_port);
 // Make HTTP POST Header
 memset(send_buffer, '', SEND_BUFFER_SIZE);
 len = strlen(content);
 MakePOSTHeader(send_buffer, len, DELETE_PORT);
 strcat(send_buffer, content);
 //#ifdef UPNP_DEBUG
 printf("%srn", send_buffer);
 //#endif
 ipaddr = inet_addr((unsigned char *)descIP);
 ipaddr = swapl(ipaddr);
 port   = ATOI(descPORT, 10);
 // Connect to IGD(Internet Gateway Device)
 close(sockfd);
 socket(sockfd, Sn_MR_TCP, PORT_UPNP, Sn_MR_ND); /*Open a port of the socket*/
 while (getSn_SR(sockfd) != SOCK_INIT);
 if (connect(sockfd, (unsigned char *)&ipaddr, port) == 0)
     printf("TCP Socket Error!!rn");
 // Send "Delete Port" Message
 while (getSn_SR(sockfd) != SOCK_ESTABLISHED);
 send(sockfd, (void *)send_buffer, strlen(send_buffer));
 // Receive Reply
 memset(recv_buffer, '', RECV_BUFFER_SIZE);
 delay_ms(500);
 endTime = my_time + 3;
 while (recv(sockfd, (void *)recv_buffer, RECV_BUFFER_SIZE) <= 0 && my_time < endTime); // Check Receive Buffer 
 if (my_time >= endTime)
 {                                                                                      // Check Timeout
     close(sockfd);
     return -1;
 }
 // TCP Socket Close
 close(sockfd);
 //#ifdef UPNP_DEBUG
 printf("rnReceiveDatarn%srn", recv_buffer);
 //#endif
 // Parse Replied Message
 return parseDeletePort(recv_buffer);
}

首先會通過MakeSOAPDeleteControl()函數(shù)組裝請求報文中的XML部分,具體內(nèi)容如下:

/**
* @brief   This function makes the Delete Port Control message in SOAP.
* @param   dest:Target string pointer
* @param   protocol:Protocol type
* @param   extertnal_port:External port
* @return  none
*/
void MakeSOAPDeleteControl(char *dest, const char *protocol, const unsigned int extertnal_port)
{
    char local_port[6] = {''};
    strcat(dest, soap_start);
    strcat(dest, DeletePortMapping_);
    strcat(dest, NewRemoteHost_);
    strcat(dest, _NewRemoteHost);
    strcat(dest, NewExternalPort_);
    sprintf(local_port, "%d", extertnal_port);
    strcat(dest, local_port);
    strcat(dest, _NewExternalPort);
    strcat(dest, NewProtocol_);
    strcat(dest, protocol);
    strcat(dest, _NewProtocol);
    strcat(dest, _DeletePortMapping);
    strcat(dest, soap_end);
}

然后通過MakePOSTHeader()函數(shù)制作HTTP頭部內(nèi)容,具體內(nèi)容如下:

 /**
* @brief   This function makes the HTTP POST Header.
* @param   dest:Target string pointer
* @param   content_length: content length
* @param   action: action type
* @return  none
*/
void MakePOSTHeader(char *dest, int content_length, int action)
{
   char local_length[6] = {''}, local_port[6] = {''};
   sprintf(local_length, "%d", content_length);
   strcat(dest, "POST ");
   strcat(dest, controlURL);
   strcat(dest, " HTTP/1.1rn");
   strcat(dest, "Content-Type: text/xml; charset="utf-8"rn");
   strcat(dest, "SOAPAction: "urn:schemas-upnp-org:service:WANIPConnection:1#");
   switch (action)
   {
   case DELETE_PORT:
       strcat(dest, "DeletePortMapping"");
       break;
   case ADD_PORT:
       strcat(dest, "AddPortMapping"");
       break;
   }
   strcat(dest, "rnUser-Agent: Mozilla/4.0 (compatible; UPnP/1.0; Windows NT/5.1)rn");
   strcat(dest, "Host: ");
   strcat(dest, descIP);
   sprintf(local_port, ":%s", descPORT);
   strcat(dest, local_port);
   strcat(dest, "rnContent-Length: ");
   strcat(dest, local_length);
   strcat(dest, "rnConnection: Keep-AlivernCache-Control: no-cachernPragma: no-cachernrn");
}

最后則是發(fā)送請求,然后通過parseDeletePort()函數(shù)解析響應內(nèi)容判斷是否添加端口映射成功。

signed short parseDeletePort(
 const char *xml /**< string for parse */
)
{
 parseHTTP(xml);
 if (strstr(xml, "u:DeletePortMappingResponse xmlns:u="urn:schemas-upnp-org:service:WANIPConnection:1"") == NULL)
 {
     return parseError(xml);
 }
 return 0;
}

7運行結(jié)果

燒錄例程運行后,首先進行了PHY鏈路檢測,然后是通過DHCP獲取網(wǎng)絡地址并打印網(wǎng)絡地址信息:

wKgZO2iBk_qAJu0hAACGbFXSs4s753.png

接下來是搜索IGD設備,搜索成功后會進行獲取設備描述以及設置訂閱IGD事件,全部成功后則進入主菜單。

wKgZPGiBk_qAR8NXAAB7KK65PqM552.png

接著,我們輸入7,添加一個TCP協(xié)議的端口映射,外部端口為12345,內(nèi)部端口為8000。

wKgZPGiBlUGAJUKXAAB_qiS29yE458.png

打開UPnP Wizard軟件,點擊刷新后可以看到我們添加的端口映射表。(UPnP Wizard下載鏈接:https://upnp-wizard.en.softonic.com/)

wKgZPGiBk_qAPl1rAABLZ3dYYI0094.png

然后我們輸入5,打開TCP回環(huán)測試程序。

wKgZO2iBk_qAPyybAAB2Yd2UAUQ634.png

隨后,我們打開一個網(wǎng)絡調(diào)試助手,例如SocketTester,選擇為TCP Client模式,服務器地址為外部IP地址也就是192.168.1.135,端口號為外部端口號12345,點擊”Connect”連接后,可以看到成功連接到內(nèi)部的W55MH32上了。UDP也是同樣進行操作,這里不再演示。

wKgZPGiBk_uAWsuuAABgCNp5Vw4452.png

接著我們輸入Q退出回環(huán)測試程序,然后輸入8,將之前添加的TCP協(xié)議的12345外部端口刪除。在UPnP Wizard上點擊刷新,可以看到已經(jīng)成功刪除,再次執(zhí)行回環(huán)測試程序,已經(jīng)無法連接上內(nèi)部的W55MH32上。

wKgZPGiBk_qAHCnnAACLZa5NCuc107.pngwKgZO2iBk_qATGsqAADLCfGoIX0170.pngwKgZO2iBk_qAdqobAAAnyGquMak336.pngwKgZO2iBk_uAH-J3AACQC9YpHyc941.png

8總結(jié)

本文講解了如何在 W55MH32芯片上實現(xiàn) UPnP協(xié)議的端口轉(zhuǎn)發(fā)功能,通過實戰(zhàn)例程詳細展示了從設備搜索、獲取設備描述、訂閱事件到添加和刪除端口映射的完整流程,包括各步驟涉及的協(xié)議報文、函數(shù)實現(xiàn)和具體操作。文章還對 UPnP協(xié)議的簡介、特點、應用場景進行了分析,幫助讀者理解其在網(wǎng)絡設備互聯(lián)互通中的實際應用價值。

下一篇文章將聚焦 TFTP協(xié)議,解析其核心原理及在文件傳輸中的應用,同時講解如何在W55MH32上實現(xiàn) TFTP功能,敬請期待!

WIZnet是一家無晶圓廠半導體公司,成立于 1998年。產(chǎn)品包括互聯(lián)網(wǎng)處理器 iMCU?,它采用 TOE(TCP/IP卸載引擎)技術,基于獨特的專利全硬連線 TCP/IP。iMCU?面向各種應用中的嵌入式互聯(lián)網(wǎng)設備。

WIZnet在全球擁有 70多家分銷商,在香港、韓國、美國設有辦事處,提供技術支持和產(chǎn)品營銷。

香港辦事處管理的區(qū)域包括:澳大利亞、印度、土耳其、亞洲(韓國和日本除外)。

審核編輯 黃宇

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

    關注

    41

    文章

    5684

    瀏覽量

    176251
  • 端口
    +關注

    關注

    4

    文章

    1048

    瀏覽量

    32992
  • UPnP
    +關注

    關注

    0

    文章

    7

    瀏覽量

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

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    第二十六章 W55MH32?上位機搜索和配置示例

    本文講解了如何在 W55MH32?芯片上實現(xiàn)上位機搜索和配置功能,通過實戰(zhàn)例程展示了使用開源上位機配置工具 SmartConfigTool?搜索局域網(wǎng)中的 W55MH32?并進行網(wǎng)絡地址配置的過程
    的頭像 發(fā)表于 07-24 16:13 ?90次閱讀
    第二十六章 <b class='flag-5'>W55MH32</b>?上位機搜索和配置<b class='flag-5'>示例</b>

    第二十三章 W55MH32 MQTT_OneNET示例

    本文講解了如何在 W55MH32?芯片上實現(xiàn) MQTT?協(xié)議并連接 OneNET?平臺,通過實戰(zhàn)例程展示了從準備工作、連接配置到消息訂閱、發(fā)布及接收處理的完整過程。文章詳細介紹了 MQTT?協(xié)議
    的頭像 發(fā)表于 07-24 14:59 ?133次閱讀
    第二<b class='flag-5'>十三章</b> <b class='flag-5'>W55MH32</b> MQTT_OneNET<b class='flag-5'>示例</b>

    第十八章 W55MH32 FTP_Server示例

    本文講解了如何在 W55MH32?芯片上實現(xiàn) FTP?協(xié)議的服務器模式,通過實戰(zhàn)例程展示了使用 W55MH32?作為 FTP?服務器與 PC?端進行文件傳輸、目錄操作等功能的過程,涵蓋獲取網(wǎng)絡配置
    的頭像 發(fā)表于 07-24 11:55 ?56次閱讀
    <b class='flag-5'>第十</b>八章 <b class='flag-5'>W55MH32</b> FTP_Server<b class='flag-5'>示例</b>

    第十七章 W55MH32 ARP示例

    文講解了如何在 W55MH32?芯片上通過 MAC RAW?模式實現(xiàn) ARP?協(xié)議,將 IP?地址解析為 MAC?地址,通過實戰(zhàn)例程展示了從發(fā)送 ARP?請求到接收并處理響應的完整過程。文章詳細介紹
    的頭像 發(fā)表于 07-24 11:49 ?158次閱讀
    <b class='flag-5'>第十</b>七章 <b class='flag-5'>W55MH32</b> ARP<b class='flag-5'>示例</b>

    第十六章 W55MH32 PING示例

    本文講解了如何在 W55MH32?芯片上通過 IPRAW?模式實現(xiàn) ICMP?協(xié)議中的 PING?命令,以進行網(wǎng)絡連通性測試,通過實戰(zhàn)例程展示了從發(fā)送 PING?請求、接收并解析回復到統(tǒng)計結(jié)果的完整
    的頭像 發(fā)表于 07-24 11:41 ?63次閱讀
    <b class='flag-5'>第十</b>六章 <b class='flag-5'>W55MH32</b> PING<b class='flag-5'>示例</b>

    第十五章 W55MH32 SNMP示例

    本文講解了如何在 W55MH32?芯片上實現(xiàn) SNMP?功能,通過實戰(zhàn)例程展示了使用 MIB Browser?管理 W55MH32?的具體過程,涵蓋在 MIB Browser?中創(chuàng)建分支、添加葉子
    的頭像 發(fā)表于 07-24 10:43 ?150次閱讀
    <b class='flag-5'>第十</b>五章 <b class='flag-5'>W55MH32</b> SNMP<b class='flag-5'>示例</b>

    第十四章 W55MH32 TFTP示例

    本文講解了如何在 W55MH32?芯片上實現(xiàn) TFTP?協(xié)議,通過實戰(zhàn)例程詳細展示了使用 TFTP?客戶端模式從服務器獲取文本文件的過程,涵蓋 TFTP?初始化、發(fā)送讀請求、運行協(xié)議并處理結(jié)果等核心
    的頭像 發(fā)表于 07-24 10:37 ?141次閱讀
    <b class='flag-5'>第十</b>四章 <b class='flag-5'>W55MH32</b> TFTP<b class='flag-5'>示例</b>

    第十二章 W55MH32 NetBIOS示例

    本文講解了如何在 W55MH32?芯片上實現(xiàn) NetBIOS?功能,通過實戰(zhàn)例程展示了利用 NetBIOS?進行名稱 PING?測試的具體過程,包括 NetBIOS?功能的調(diào)用、請求處理、名稱解析
    的頭像 發(fā)表于 07-24 09:58 ?138次閱讀
    <b class='flag-5'>第十</b>二章 <b class='flag-5'>W55MH32</b> NetBIOS<b class='flag-5'>示例</b>

    第十一章 W55MH32 SMTP示例

    本文講解了如何在 W55MH32?芯片上實現(xiàn) SMTP?協(xié)議,通過實例詳細展示了在該芯片上使用 SMTP?協(xié)議發(fā)送電子郵件的實現(xiàn)流程,包括 SMTP?發(fā)送內(nèi)容初始化、使用 DNS?協(xié)議解析 SMTP
    的頭像 發(fā)表于 07-24 09:49 ?131次閱讀
    <b class='flag-5'>第十</b>一章 <b class='flag-5'>W55MH32</b> SMTP<b class='flag-5'>示例</b>

    第十W55MH32 SNTP示例

    本文講解了如何在W55MH32芯片上實現(xiàn)SNTP授時功能,通過實例詳細展示了從SNTP服務器同步時間的實現(xiàn)流程,包括時間請求、響應解析和本地時間校準等核心步驟。文章還對SNTP的應用場景進行了分析,幫助讀者理解其在時間同步中的實際應用價值。
    的頭像 發(fā)表于 07-24 09:43 ?159次閱讀
    <b class='flag-5'>第十</b>章 <b class='flag-5'>W55MH32</b> SNTP<b class='flag-5'>示例</b>

    第九章 W55MH32 HTTP Server示例

    本文介紹了在 W55MH32?芯片上實現(xiàn) HTTP Server?功能,并通過瀏覽器修改其網(wǎng)絡地址信息的方法。闡述了 HTTP?協(xié)議的概念、特點、應用場景、工作流程、請求方法、響應內(nèi)容,以及 Web?頁面構(gòu)成和交互方式。展示了在W55MH32上實現(xiàn)的過程。
    的頭像 發(fā)表于 07-24 09:35 ?125次閱讀
    第九章 <b class='flag-5'>W55MH32</b> HTTP Server<b class='flag-5'>示例</b>

    第五章 W55MH32 UDP示例

    本文介紹了在 W55MH32?芯片上實現(xiàn) UDP?通信及數(shù)據(jù)回環(huán)測試的方法。闡述了 UDP?協(xié)議的概念、特點、應用場景、報文傳輸流程和報文結(jié)構(gòu),展示了實現(xiàn)過程,借助網(wǎng)絡調(diào)試工具完成測試。
    的頭像 發(fā)表于 07-24 09:13 ?95次閱讀
    第五章 <b class='flag-5'>W55MH32</b> UDP<b class='flag-5'>示例</b>

    三章 W55MH32 TCP Client示例

    本文介紹在 W55MH32?芯片上實現(xiàn) TCP?客戶端模式進行數(shù)據(jù)回環(huán)測試的方法。闡述 TCP?協(xié)議概念、特點、與 UDP?區(qū)別、應用場景及相關機制。展示實現(xiàn)過程,包括開啟 Keepalive?功能,在主循環(huán)運行測試程序。燒錄例程后進行 PHY?鏈路檢測、獲取網(wǎng)絡地址,再借助網(wǎng)絡調(diào)試工具測試。
    的頭像 發(fā)表于 07-24 09:06 ?159次閱讀
    第<b class='flag-5'>三章</b> <b class='flag-5'>W55MH32</b> TCP Client<b class='flag-5'>示例</b>

    第二章 W55MH32 DHCP示例

    本文介紹 DHCP?協(xié)議,包括其在 IP?網(wǎng)絡自動分配參數(shù)的功能、便捷配置等特點、工作原理、報文格式和應用場景。通過 W55MH32?實戰(zhàn)例程展示動態(tài)獲取網(wǎng)絡地址信息過程,含注冊定時器中斷、啟用模式和獲取信息等步驟,燒錄后可完成檢測與信息打印,PC?端能 PING?通設備。
    的頭像 發(fā)表于 07-24 09:02 ?152次閱讀
    第二章 <b class='flag-5'>W55MH32</b> DHCP<b class='flag-5'>示例</b>

    WIZnet W55MH32以太網(wǎng)單片機開發(fā)教程 第十一章 通用定時器(上篇)

    本章介紹了W55MH32的通用定時器TIM2~TIM5,其由 16 位計數(shù)器等構(gòu)成,具輸入捕獲等功能,有多種計數(shù)模式及時鐘選擇。對例程進行了講解并下載驗證,TIM9~14功能類似,詳見《W55MH32參考手冊》。
    的頭像 發(fā)表于 05-28 10:12 ?399次閱讀
    WIZnet <b class='flag-5'>W55MH32</b>以太網(wǎng)單片機開發(fā)教程 <b class='flag-5'>第十</b>一章 通用定時器(上篇)