2023-05-31 16:56:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								lwIP
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								====
 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-21 18:01:26 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-31 16:56:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								:link_to_translation:`en:[English]` 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								ESP-IDF 使用开源的 `lwIP 轻量级 TCP/IP 协议栈`_ ,该版 lwIP (`esp-lwip`_ ) 相对上游项目做了修改和增补。
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								支持的 API
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								--------------
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								ESP-IDF 支持以下 lwIP TCP/IP 协议栈功能:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  `BSD 套接字 API`_ 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  `Netconn API`_  已启用,但暂无对 ESP-IDF 应用程序的官方支持
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								适配的 API
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								^^^^^^^^^^^^
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    ..  warning :: 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								        在使用除 `BSD 套接字 API`_  外的任意 lwIP API 时,请确保所用 API 为线程安全。请启用 :ref: `CONFIG_LWIP_CHECK_THREAD_SAFETY`  配置选项并运行应用程序,检查所用 API 是否线程安全。此时, `lwIP FreeRTOS 任务`_  访问,或没有正确锁定,则执行中止。建议使用 :doc: `/api-reference/network/esp_netif`  组件与 lwIP 交互。
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								ESP-IDF 间接支持以下常见的 lwIP 应用程序 API: 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  动态主机设置协议 (DHCP) 服务器和客户端,由 :doc: `/api-reference/network/esp_netif`  功能间接支持。
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								-  简单网络时间协议 (SNTP),由 :doc: `/api-reference/network/esp_netif`  功能间接支持,或通过 :component_file:`lwip/include/apps/esp_sntp.h` `lwip/lwip/src/include/lwip/apps/sntp.h` , :ref: `system-time-sntp-sync` 。
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								-  ICMP Ping, :doc: `/api-reference/protocols/icmp_echo` 。
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								-  ICMPv6 Ping, :example: `protocols/sockets/icmpv6_ping` 。
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  NetBIOS 查找,由标准的 lwIP API 支持,:example: `protocols/http_server/restful_server`  示例中提供了使用 NetBIOS 在局域网中查找主机的选项。
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								-  mDNS 与 lwIP 的默认 mDNS 使用不同实现方式,请参阅 :doc: `/api-reference/protocols/mdns` 。但启用 :ref: `CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES`  设置项后, `` gethostbyname() ``  等标准 API 和 `` hostname.local ``  约定查找 mDNS 主机。
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								-  lwIP 中的 PPP 实现可用于在 ESP-IDF 中创建 PPPoS( ) :doc: `/api-reference/network/esp_netif`  组件文档,使用 :component_file:`esp_netif/include/esp_netif_defaults.h` 中定义的 ``ESP_NETIF_DEFAULT_PPP()`` 宏创建并配置 PPP 网络接口。:component_file:`esp_netif/include/esp_netif_ppp.h` 中提供了其他的运行时设置。PPPoS 接口通常用于与 NBIoT/GSM/LTE 调制解调器交互。`esp_modem  <https://components.espressif.com/component/espressif/esp_modem> `_  仓库还支持更多应用层友好的 API, 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								BSD 套接字 API
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-----------------
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								BSD 套接字 API 是一种常见的跨平台 TCP/IP 套接字 API, 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								在 ESP-IDF 中, 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								参考
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								^^^^^^^^^^
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								BSD 套接字的相关参考资料十分丰富,包括但不限于:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  `单一 UNIX 规范 - BSD 套接字  <https://pubs.opengroup.org/onlinepubs/007908799/xnsix.html> `_ 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  `伯克利套接字 - 维基百科  <https://en.wikipedia.org/wiki/Berkeley_sockets> `_ 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								示例
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								^^^^^^^^
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								以下为 ESP-IDF 中使用 BSD 套接字 API 的部分示例:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  :example: `protocols/sockets/tcp_server` 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  :example: `protocols/sockets/tcp_client` 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  :example: `protocols/sockets/udp_server` 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  :example: `protocols/sockets/udp_client` 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  :example: `protocols/sockets/udp_multicast` 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  :example: `protocols/http_request` :此简化示例使用 TCP 套接字发送 HTTP 请求,但更推荐使用 :doc: `/api-reference/protocols/esp_http_client`  发送 HTTP 请求
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								支持的函数
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								^^^^^^^^^^^^^^^^^^^
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								在 ESP-IDF 中, `lwip/lwip/src/include/lwip/sockets.h` 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  `` socket() `` 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  `` bind() `` 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  `` accept() `` 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  `` shutdown() `` 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  `` getpeername() `` 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  `` getsockopt() ``  和 `` setsockopt() ` ` :请参阅  ` 套接字选项 ` _
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  `` close() ` ` :通过 :doc: ` /api-reference/storage/vfs `  调用
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  `` read() ` ` 、 ` ` readv() ` ` 、 ` ` write() ` ` 、 ` ` writev() ` ` :通过 :doc: ` /api-reference/storage/vfs `  调用
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  `` recv() ` ` 、 ` ` recvmsg() ` ` 、 ` ` recvfrom() `` 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  `` send() ` ` 、 ` ` sendmsg() ` ` 、 ` ` sendto() `` 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  `` select() ` ` :通过 :doc: ` /api-reference/storage/vfs `  调用
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								-  `` poll() ` ` : ` ` select() ``  实现 `` poll() ` ` ,因此,建议直接调用  ` ` select() `` 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  `` fcntl() ` ` :请参阅  ` fcntl() ` _
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								非标准函数:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  `` ioctl() ` ` :请参阅  ` ioctl() ` _
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								..  note :: 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								  部分 lwIP 应用程序示例代码使用了带前缀的 BSD API, `` lwip_socket() ` ` ,而非标准  ` ` socket() ` ` 。ESP-IDF 支持使用以上两种形式,但更建议使用标准名称。
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								套接字错误处理
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								^^^^^^^^^^^^^^^^^^^^^
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								要使套接字应用程序保持稳定, 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  错误检测
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  获取错误原因代码
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  根据错误原因代码处理错误
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								在 lwIP 中,处理套接字错误分以下两种情况:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  套接字 API 返回错误,请参阅 `套接字 API 错误`_ 。
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  `` select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset, struct timeval *timeout) ``  包含异常描述符,表示套接字出现错误,详情请参阅 `select() 错误`_ 。
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								套接字 API 错误
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								+++++++++++++++++
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								**错误检测** 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								  -  根据返回值判断套接字 API 是否出错。
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								**获取错误原因代码** 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								  -  套接字 API 出错时,其返回值不包含失败原因,可以通过应用程序访问 `` errno ``  获取错误原因代码。不同返回值具有不同含义,详情请参阅 `套接字错误原因代码`_ 。
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								示例:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								..  code-block :: 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        int err;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        int sockfd;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if (sockfd = socket(AF_INET,SOCK_STREAM,0) < 0) {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // 从 errno 获取错误代码
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            err = errno;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return err;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        }
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								`` select() ``  错误
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								+++++++++++++++++++++++
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								**错误检测** 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								  -  `` select() ``  包含异常描述符时的套接字错误。
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								**获取错误原因代码** 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								  -  如果 `` select() ``  报告套接字错误,访问 `` errno ``  无法获取错误原因代码,此时,应调用 `` getsockopt() ` ` 。因为当  ` ` select() ``  包含异常描述符时,错误代码不会直接赋值给 `` errno ` ` 。
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								..  note :: 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    `` getsockopt() ``  函数具有以下原型:`` int getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen) ` ` 。原型可以获取任意类型、任意状态套接字选项的当前值,并将结果存储在  ` ` optval ``  中。例如,要在套接字上获取错误代码,可以通过 `` getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &err, &optlen) ``  实现。
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								示例:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								..  code-block :: 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        int err;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if (select(sockfd + 1, NULL, NULL, &exfds, &tval) <= 0) {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            err = errno;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return err;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } else {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if (FD_ISSET(sockfd, &exfds)) {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                // 使用 getsockopt() 获取 select() 异常集
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                int optlen = sizeof(int);
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &err, &optlen);
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return err;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            }
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        }
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								套接字错误原因代码
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								++++++++++++++++++++++++
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								以下是常见错误代码列表。有关标准 POSIX/C 错误代码的详细列表,请参阅 `newlib errno.h  <https://github.com/espressif/newlib-esp32/blob/master/newlib/libc/include/sys/errno.h> `_  和特定平台扩展 :component_file:`newlib/platform_include/errno.h` 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								..  list-table :: 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    :header-rows:  1 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    :widths:  50 50 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    :align:  center 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    *  - 错误代码
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								      -  描述
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    *  - ECONNREFUSED
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								      -  拒绝连接
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    *  - EADDRINUSE
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								      -  地址已在使用中
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    *  - ECONNABORTED
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								      -  软件导致连接中断
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    *  - ENETUNREACH
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								      -  网络不可达
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    *  - ENETDOWN
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								      -  未配置网络接口
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    *  - ETIMEDOUT
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								      -  连接超时
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    *  - EHOSTDOWN
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								      -  主机已关闭
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    *  - EHOSTUNREACH
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								      -  主机不可达
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    *  - EINPROGRESS
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								      -  连接已在进行中
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    *  - EALREADY
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								      -  套接字已连接
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    *  - EDESTADDRREQ
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								      -  需要目标地址
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    *  - EPROTONOSUPPORT
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								      -  未知协议
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								套接字选项
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								^^^^^^^^^^^^^^
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								`` getsockopt() ``  支持获取套接字选项,`` setsockopt() ``  支持设置套接字选项。
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								在 ESP-IDF 中, 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								常见选项
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								++++++++++++++
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								与级别参数 `` SOL_SOCKET ``  一起使用。
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  `` SO_REUSEADDR ` ` :如果 :ref: ` CONFIG_LWIP_SO_REUSE `  已启用,则该选项可用,可以设置 :ref: ` CONFIG_LWIP_SO_REUSE_RXTOALL `  自定义其行为
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  `` SO_KEEPALIVE `` 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  `` SO_BROADCAST `` 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  `` SO_ACCEPTCONN `` 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  `` SO_RCVBUF ` ` :如果 :ref: ` CONFIG_LWIP_SO_RCVBUF `  已启用,则该选项可用
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  `` SO_SNDTIMEO ``  / `` SO_RCVTIMEO `` 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  `` SO_ERROR ` ` :此选项仅支持与  ` ` select() ``  一起使用,请参阅 `套接字错误处理`_ 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  `` SO_TYPE `` 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  `` SO_NO_CHECK ` ` :仅适用于 UDP 套接字
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								IP 选项
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								++++++++++
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								与级别参数 `` IPPROTO_IP ``  一起使用。
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  `` IP_TOS `` 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  `` IP_TTL `` 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  `` IP_PKTINFO ` ` :如果 :ref: ` CONFIG_LWIP_NETBUF_RECVINFO `  已启用,则该选项可用
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								对于组播 UDP 套接字:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  `` IP_MULTICAST_IF `` 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  `` IP_MULTICAST_LOOP `` 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  `` IP_MULTICAST_TTL `` 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  `` IP_ADD_MEMBERSHIP `` 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  `` IP_DROP_MEMBERSHIP `` 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								TCP 选项
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								+++++++++++
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								只适用于 TCP 套接字,与级别参数 `` IPPROTO_TCP ``  一起使用。
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  `` TCP_NODELAY `` 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								与 TCP 保活探测相关的选项:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  `` TCP_KEEPALIVE ` ` :整数值,以毫秒为单位,设置 TCP 保活探测周期
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  `` TCP_KEEPIDLE ` ` :整数值,以秒为单位,与  ` ` TCP_KEEPALIVE ``  相同
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  `` TCP_KEEPINTVL ` ` :整数值,以秒为单位,设置保活探测间隔
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  `` TCP_KEEPCNT ` ` :整数值,设置超时前进行的保活探测次数
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								IPv6 选项
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								++++++++++++
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								只适用于 IPv6 套接字,与级别参数 `` IPPROTO_IPV6 ``  一起使用。
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  `` IPV6_CHECKSUM `` 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  `` IPV6_V6ONLY `` 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								对于组播 IPv6 UDP 套接字:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  `` IPV6_JOIN_GROUP ``  / `` IPV6_ADD_MEMBERSHIP `` 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  `` IPV6_LEAVE_GROUP ``  / `` IPV6_DROP_MEMBERSHIP `` 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  `` IPV6_MULTICAST_IF `` 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  `` IPV6_MULTICAST_HOPS `` 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  `` IPV6_MULTICAST_LOOP `` 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								`` fcntl() `` 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								^^^^^^^^^^^
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								`` fcntl() ``  函数是设置与文件描述符相关选项的标准 API。在 ESP-IDF 中,使用 :doc: `/api-reference/storage/vfs`  层实现该函数。
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								当文件描述符为套接字时,仅支持以下 `` fcntl() ``  值:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  `` O_NONBLOCK ``  用于置位或清除非阻塞 I/O 模式。`` O_NDELAY ``  也受支持,与前者功能相同。
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								-  `` O_RDONLY ` ` 、 ` ` O_WRONLY ` ` 、 ` ` O_RDWR ``  标志用于不同的读或写模式,只能用 `` F_GETFL ``  读取,且无法用 `` F_SETFL ``  设置。根据连接状况, , `` O_RDWR ` ` 。
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								`` ioctl() `` 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								^^^^^^^^^^^
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								`` ioctl() ``  函数以半标准的方式访问 TCP/IP 协议栈的部分内部功能。ESP-IDF 通过 :doc: `/api-reference/storage/vfs`  层实现此函数。
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								当文件描述符为套接字时,仅支持以下 `` ioctl() ``  值:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  `` FIONREAD ``  返回套接字网络 buffer 中接收的待处理字节数。
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  `` FIONBIO ``  和 `` fcntl(fd, F_SETFL, O_NONBLOCK, ...) ``  相同,也可置位或清除套接字非阻塞 I/O 状态。
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								Netconn API
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-----------
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								lwIP 支持两种较低级别的 API 和 BSD 套接字 API, 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								lwIP Raw API 适用于单线程设备,无法在 ESP-IDF 中使用。
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								Netconn API 用于在 lwIP 内部使用 BSD 套接字 API, , , 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								..  important :: 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								    乐鑫尚未在 ESP-IDF 中测试 Netconn API, **此功能已启用,但尚无官方支持** 。对于某些功能,可能只有在从 BSD 套接字 API 中使用时才能正常运作。
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								有关 Netconn API 的更多信息,请参阅 `lwip/lwip/src/include/lwip/api.h  <http://www.nongnu.org/lwip/2_0_x/api_8h.html> `_  和 `lwIP 应用程序 **非官方** 开发手册的一部分  <https://lwip.fandom.com/wiki/Netconn_API> `_ 。
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								lwIP FreeRTOS 任务
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								------------------
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								lwIP 创建了专用的 TCP/IP FreeRTOS 任务,处理来自其他任务的套接字 API 请求。
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								以下配置项可用于修改任务,并调整向 TCP/IP 任务发送数据和从 TCP/IP 任务接收数据的队列(邮箱):
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  :ref: `CONFIG_LWIP_TCPIP_RECVMBOX_SIZE` 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  :ref: `CONFIG_LWIP_TCPIP_TASK_STACK_SIZE` 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  :ref: `CONFIG_LWIP_TCPIP_TASK_AFFINITY` 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								IPv6 支持
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								------------
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								系统支持 IPv4 和 IPv6 的双栈功能,并默认启用这两种协议。如无需要,可将其禁用,请参阅 :ref: `lwip-ram-usage` 。
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								在 ESP-IDF 中, **无状态自动配置** ,不支持 **有状态配置** ,上游的 lwIP 也不支持 **有状态配置** 。
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								IPv6 地址配置通过以下协议或服务定义:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  支持 **SLAAC**  IPv6 无状态地址配置 (RFC-2462)
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  支持 **DHCPv6**  IPv6 动态主机配置协议 (RFC-8415)
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								以上两种地址配置默认处于禁用状态,设备仅使用链路本地地址或静态定义的地址。
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								..  _lwip-ivp6-autoconfig: 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								无状态自动配置流程
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								要通过路由器通告协议启用地址自动配置,请启用此配置选项:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  :ref: `CONFIG_LWIP_IPV6_AUTOCONFIG` 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								该配置选项启用了所有网络接口的 IPv6 自动配置。而在上游 lwIP 中,需要设置 `` netif->ip6_autoconfig_enabled=1 ` ` ,针对每个  ` ` netif ``  明确启用自动配置。
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								..  _lwip-ivp6-dhcp6: 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								DHCPv6
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								^^^^^^
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								lwIP 中的 DHCPv6 非常简单,仅支持无状态配置,可通过以下配置选项启用:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  :ref: `CONFIG_LWIP_IPV6_DHCP6` 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								由于 DHCPv6 仅在无状态配置下工作,因此还需要通过 :ref: `CONFIG_LWIP_IPV6_AUTOCONFIG`  启用 :ref: `lwip-ivp6-autoconfig` 。
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								此外,还需要使用以下语句,在应用程序代码中明确启用 DHCPv6: 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								..  code-block :: 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    dhcp6_enable_stateless(netif);
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								IPv6 自动配置中的 DNS 服务器
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								要自动配置 DNS 服务器,尤其是在仅使用 IPv6 的网络中配置,可使用以下两种选项:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  递归域名系统 (DNS),属于邻居发现协议 (NDP) 的一部分,可使用 :ref: `lwip-ivp6-autoconfig` 。
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								  DNS 服务器的数量必须设置为 :ref: `CONFIG_LWIP_IPV6_RDNSS_MAX_DNS_SERVERS` ,该选项默认禁用,即置位为 0。
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  DHCPv6 无状态配置,使用 :ref: `lwip-ivp6-dhcp6`  配置 DNS 服务器。注意,此配置假设 IPv6 路由通告标志 (RFC-5175) 进行了如下设置
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    -  管理地址配置标志 (Managed Address Configuration Flag) = 0
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    -  其他配置标志 (Other Configuration Flag) = 1
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								ESP-lwIP 自定义修改
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-----------------------------
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								补充内容
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								^^^^^^^^^
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								以下代码均为新增代码,尚未包含至上游 lwIP 版本:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								线程安全的套接字
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								+++++++++++++++++++
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								调用 `` close() ``  可以从不同于创建套接字的线程中关闭该套接字。该调用持续阻塞,直至其他任务中使用该套接字的函数调用返回。
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								然而,任务处于主动等待 `` select() ``  或 `` poll() ``  API 的状态时,无法删除该任务。销毁任务前,这些 API 必须先退出,否则可能会破坏内部数据结构,并导致后续 lwIP 崩溃。这些 API 在栈上分配了全局引用的回调指针, , , 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								按需定时器
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								++++++++++++++++
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								lwIP 中的 IGMP 和 MLD6 功能都会初始化一个定时器,以便在特定时间触发超时事件。
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								即便没有活动的超时事件, `` ESP-lwIP ``  则默认将各定时器设置为 `` 按需 ``  使用,即只在有待处理事件时启用。
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								如果要返回默认 lwIP 设置,即始终启用定时器,请禁用 :ref: `CONFIG_LWIP_TIMERS_ONDEMAND` 。
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								lwIP 定时器 API
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								+++++++++++++++
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								不使用 Wi-Fi 时,可以通过 API 关闭 lwIP 定时器,减少功耗。
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								以下 API 函数均受支持,详情请参阅 :component_file:`lwip/lwip/src/include/lwip/timeouts.h` 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  `` sys_timeouts_init() `` 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  `` sys_timeouts_deinit() `` 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								附加套接字选项
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								+++++++++++++++++++++++++
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  目前已实现部分标准 IPV4 和 IPV6 组播套接字选项,详情请参阅 `套接字选项`_ 。
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  使用 `` IPV6_V6ONLY ``  套接字选项,可以设置仅使用 IPV6 的 UDP 和 TCP 套接字,而 lwIP 一般只支持 TCP 套接字。
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								IP 层特性
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								+++++++++++++++++
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  IPV4 源地址基础路由实现不同
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  支持 IPV4 映射 IPV6 地址
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								自定义 lwIP 钩子
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								+++++++++++++++++++++
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								原始 lwIP 支持通过 `` LWIP_HOOK_FILENAME ``  实现自定义的编译时修改。ESP-IDF 端口层已使用该文件,但仍支持通过由宏 `` ESP_IDF_LWIP_HOOK_FILENAME ``  定义的头文件,在 ESP-IDF 中包含并实现自定义添加。以下示例展示了向构建过程添加自定义钩子文件的过程,其中钩子文件名为 `` my_hook.h ` ` ,位于项目的  ` ` main ``  文件夹中:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								..  code-block ::  cmake
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								   idf_component_get_property(lwip lwip COMPONENT_LIB)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								   target_compile_options(${lwip} PRIVATE "-I${PROJECT_DIR}/main")
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								   target_compile_definitions(${lwip} PRIVATE "-DESP_IDF_LWIP_HOOK_FILENAME=\"my_hook.h\"")
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								限制
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								^^^^^^^^^^^
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								在 UDP 套接字上重复调用 `` send() ``  或 `` sendto() ``  最终可能会导致错误。此时 `` errno ``  报错为 `` ENOMEM ` ` ,错误原因是底层网络接口驱动程序中的 buffer 大小有限。当所有驱动程序的传输 buffer 已满时,  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								..  only ::  esp32
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    在 :ref: `Wi-Fi <CONFIG_ESP_WIFI_TX_BUFFER>`  或 :ref: `Ethernet <CONFIG_ETH_DMA_TX_BUFFER_NUM>`  项目配置中适当增加传输 buffer 数量,或许可以缓解此情况。
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								..  only ::  not esp32 and SOC_WIFI_SUPPORTED
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    在 :ref: `Wi-Fi <CONFIG_ESP_WIFI_TX_BUFFER>`  项目配置中适当增加传输 buffer 数量,或许可以缓解此情况。
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								..  _lwip-performance: 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								性能优化
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								------------------------
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								影响 TCP/IP 性能因素较多, , 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								最大吞吐量
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								^^^^^^^^^^^^^^^^^^
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								在 :example: `wifi/iperf`  示例中,乐鑫测试了在射频密封的封闭环境下 ESP-IDF 的 TCP/IP 吞吐量。
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								iperf 示例下的 :example_file:`wifi/iperf/sdkconfig.defaults` , 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								..  important :: 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								  建议逐步应用更改,并在每次更改后,通过特定应用程序的工作负载检查性能。
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-10-11 17:54:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								-  如果系统中有许多任务抢占 CPU 时间,可以考虑调整 lwIP 任务的 CPU 亲和性 (:ref: `CONFIG_LWIP_TCPIP_TASK_AFFINITY` ),并以固定优先级 (18, `` ESP_TASK_TCPIP_PRIO `` ) 运行。为优化 CPU 使用,可以考虑将竞争任务分配给不同核心,或将其优先级调整至较低值。有关内置任务优先级的更多详情,请参阅 :ref: `built-in-task-priorities` 。
  
						 
					
						
							
								
									
										
										
										
											2023-05-31 16:56:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  如果使用仅带有套接字参数的 `` select() ``  函数,禁用 :ref: `CONFIG_VFS_SUPPORT_SELECT`  可以更快地调用 `` select() ` ` 。
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								-  如果有足够的空闲 IRAM, :ref: `CONFIG_LWIP_IRAM_OPTIMIZATION`  和 :ref: `CONFIG_LWIP_EXTRA_IRAM_OPTIMIZATION` ,提高 TX/RX 吞吐量。
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								..  only ::  SOC_WIFI_SUPPORTED
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    如果使用 Wi-Fi 网络接口,请参阅 :ref: `wifi-buffer-usage` 。
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								最低延迟
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								^^^^^^^^^^^^^^^
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								除增加 buffer 大小外,大多数增加吞吐量的设置会减少 lwIP 函数占用 CPU 的时间,进而降低延迟,缩短响应时间。
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								-  对于 TCP 套接字, `` TCP_NODELAY ``  标记以禁用 Nagle 算法。
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								..  _lwip-ram-usage: 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								最小内存使用
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								^^^^^^^^^^^^^^^^^
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								由于 RAM 按需从堆中分配,多数 lwIP 的 RAM 使用也按需分配。因此,更改 lwIP 设置减少 RAM 使用时,或许不会改变空闲时的 RAM 使用量,但可以改变高峰期的 RAM 使用量。
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  减少 :ref: `CONFIG_LWIP_MAX_SOCKETS`  可以减少系统中的最大套接字数量。更改此设置,会让处于 `` WAIT_CLOSE ``  状态的 TCP 套接字在需要打开新套接字时更快地关闭和复用,进一步降低峰值 RAM 使用量。
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  减少 :ref: `CONFIG_LWIP_TCPIP_RECVMBOX_SIZE` 、:ref: `CONFIG_LWIP_TCP_RECVMBOX_SIZE`  和 :ref: `CONFIG_LWIP_UDP_RECVMBOX_SIZE`  可以减少 RAM 使用量,但会影响吞吐量,具体取决于使用情况。
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								-  减少 :ref: `CONFIG_LWIP_TCP_MSL`  和 :ref: `CONFIG_LWIP_TCP_FIN_WAIT_TIMEOUT`  可以减少系统中的最大分段寿命,同时会使处于 `` TIME_WAIT ``  和 `` FIN_WAIT_2 ``  状态的 TCP 套接字能更快地关闭和复用。
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								-  禁用 :ref: `CONFIG_LWIP_IPV6`  可以在系统启动时节省大约 39 KB 的固件大小和 2 KB 的 RAM, , , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								-  禁用 :ref: `CONFIG_LWIP_IPV4`  可以在系统启动时节省大约 26 KB 的固件大小和 600 B 的 RAM, , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								..  only ::  SOC_WIFI_SUPPORTED
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								    如果使用 Wi-Fi, :ref: `wifi-buffer-usage` 。
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								最大 buffer 使用
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								+++++++++++++++++
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								lwIP 消耗的最大堆内存即 lwIP 驱动程序 **理论上可能消耗的最大内存** ,通常取决于以下因素:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								 -  创建 UDP 连接所需的内存:`` lwip_udp_conn `` 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								 -  创建 TCP 连接所需的内存:`` lwip_tcp_conn `` 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								 -  应用程序拥有的 UDP 连接数量:`` lwip_udp_con_num `` 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								 -  应用程序拥有的 TCP 连接数量:`` lwip_tcp_con_num `` 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								 -  TCP 的 TX 窗口大小:`` lwip_tcp_tx_win_size `` 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								 -  TCP 的 RX 窗口大小:`` lwip_tcp_rx_win_size `` 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								**因此,  
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								  lwip_dynamic_peek_memory =  (lwip_udp_con_num * lwip_udp_conn)  + (lwip_tcp_con_num *  (lwip_tcp_tx_win_size + lwip_tcp_rx_win_size + lwip_tcp_conn))
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								某些基于 TCP 的应用程序只需要一个 TCP 连接。然而,当出现错误(如发送失败)时,应用程序可能会关闭此 TCP 连接,并创建一个新的连接。根据 TCP 状态机和 RFC793, 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								..  _lwIP 轻量级 TCP/IP 协议栈:  https://savannah.nongnu.org/projects/lwip/
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								..  _esp-lwip:  https://github.com/espressif/esp-lwip