一、前言
最近項目的上使用有線以太網功能,軟件協議使用LWIP協議,操做系統使用Rt thread 3.1.3版本,硬件使用STM32F429+PHY LAN8720方式。這篇記錄總結lwip的詳細配置。編程
二、配置文件種類
lwip的配置文件有lwipopts.h和opt.h兩個頭文件,其餘中opt.h文件是lwip的默認配置文件,不須要修改此文件,lwipopts.h是用於配置lwip的文件,用戶的對協議的配置請在這個文件中增長與修改,lwipopts.h文件中定義宏會覆蓋到opt.h默認配置宏,讓用戶定義的新宏起做用。因爲使用操做系統rt thread, 操做系統中還有一個配置文件rtconfig.h文件,rtconfig.h中有一些關於lwip協議配置的宏。宏會被lwipopts.h所引用。api
2.1 lwIP爲使用TCP/IP協議通訊的應用程序編程提供了兩種接口接口(APIs):
* 低層次的稱之爲"core" / "callback" 或者 "raw" API緩存
* 高層次的稱之爲"sequential" API 服務器
lwIP "sequential" API爲使用TCP/IP協議棧編程提供符合常規的、通用的途徑,它與BSD socket API很是類似。程序的執行過程一樣是基於"open-read-write-close"模型的。從本質上講,TCP/IP協議棧的通訊過程是事件驅動的,所以,TCP/IP的代碼和用戶應用程序的代碼必須在不一樣的線程裏面。網絡
RAW IP容許應用程序和TCP/IP代碼緊密結合,程序的執行是基於在TCP/IP內核中被調用的回調函數事件驅動的。TCP/IP內核和應用程序能夠運行在同一線程。lwIP "sequential" API接口會消耗大量的CPU資源,它並不適用於小型嵌入式系統,由於它必須運行在多線程環境中。session
RAW API不只執行速度快,並且消耗的內存資源更少。它的缺點是應用程序編寫相對較難並不易理解。儘管如此,這種方式還是資源較少的嵌入式系統的首選方法。數據結構
不一樣的應用程序中咱們能夠同時使用這兩種APIs,實際上"sequential" API就是由RAW API封裝後獲得的。多線程
2.2 通訊接口
網絡的應用層編程通常都是基於socket接口編程 ,在建立socket時,會指定協議簇及鏈接類型,lwip協議中鏈接類型支持3種,TCP類型鏈接,UDP類型鏈接, RAW類型的鏈接。併發
socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) 建立一個tcp鏈接,協議內部使用佔用一個TCP類型的控制塊數據結構app
socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP) 建立一個udp鏈接,協議內部使用佔用一個UDP類型的控制塊數據結構
socketsocket(AF_INET , SOCK_RAW , IPPROTO_TCP) 建立一個raw(原始)鏈接,協議內部使用佔用一個RAW類型的控制塊數據結構, 此鏈接接收到的數據中包含tcp,ip的數據頭部分
三、 配置頭文件詳細說明
3.1 rtconfig配置文件
rtconfig文件用於配置整個rt thread操做系統,包括使用的lwip協議,下面只節取其中關於lwip協議部分的配置。
#define RT_USING_LWIP /*控制操做系統使用lwip協議 */ /* RT_USING_LWIP141 is not set */ #define RT_USING_LWIP202 /*選用2.0.2版本的lwip協議 */ /* RT_USING_LWIP210 is not set */ /* RT_LWIP_IGMP is not set */ /* IGMP協議關閉 */ #define RT_LWIP_ICMP /* 使能ICMP協議功能 */ /* RT_LWIP_SNMP is not set */ #define RT_LWIP_DNS /* 使能DNS 動態域名解析功能 */ #define RT_LWIP_DHCP /* 使能DHCP動態主機配置協議功能*/ #define IP_SOF_BROADCAST 1 /* 使能廣播包過濾功能 */ #define IP_SOF_BROADCAST_RECV 1 /* 使能接收廣播過濾功能 */ /* Static IPv4 Address */ #define RT_LWIP_IPADDR "192.168.10.30" /*協議配置爲靜態IP時的默認IP地址,網關地址,子網掩碼*/ #define RT_LWIP_GWADDR "192.168.10.1" #define RT_LWIP_MSKADDR "255.255.255.0" /* end of Static IPv4 Address */ #define RT_LWIP_UDP /*使能udp協議 */ #define RT_LWIP_TCP /*使能tcp協議 */ #define RT_LWIP_RAW /*使能raw接口編程,此接口是用於支持無操做系統,上層的TCP,UDP socket接口最後會調用RAW接口函數*/ /* RT_LWIP_PPP is not set */ #define RT_MEMP_NUM_NETCONN 8 /*內存池中netcon結構的數量8 這個參數控制着應用層能創建的socet的數量,也就是能同時支持多少個socket鏈接,此值應該大於MEMP_NUM_NETCONN > (MEMP_NUM_TCP_PCB+MEMP_NUM_TCP_PCB_LISTEN+MEMP_NUM_UDP_PCB+MEMP_NUM_RAW_PCB)*/ #define RT_LWIP_PBUF_NUM 16 /*pbuf的數量, pbuf用於以太網數據包的存儲並在協議棧中傳遞數據使用*/ #define RT_LWIP_RAW_PCB_NUM 4 /*協議中支持的RAW控制塊的數量,一個raw(原始)鏈接佔用一個控制塊,原始鏈接能夠額外處理IP頭,TCP頭,UDP頭等數據*/ #define RT_LWIP_UDP_PCB_NUM 4 /*協議中支持的udp控制塊的數量,一個udp鏈接佔用一個udp的控制塊*/ #define RT_LWIP_TCP_PCB_NUM 4 /*協議中支持的tcp控制塊的數量,一個tcp鏈接佔用一個tcp控制塊*/ #define RT_LWIP_TCP_SEG_NUM 40 /* TCP段的數量,應該比TCP發送段數量大TCP_SND_QUEUELEN,此數量用於分配存儲TCP數據段的內存池的數量,即程序能緩衝多少個TCP數據段*/ #define RT_LWIP_TCP_SND_BUF 8196 /* TCP發送緩存的大小,發送緩存要至少能容納2個TCP段的大小,一個TCP段的大小1460*/ #define RT_LWIP_TCP_WND 8196 /* TCP接收窗口的大小,單位字節,TCP根據本身的處理能力調節接收窗口的大小,告知發送方我如今能接收多少數據,實現了相似流量控制的功能*/ #define RT_LWIP_TCPTHREAD_PRIORITY 10 /* TCP核心處理線程的優先級,建議比底層的MAC數據的接收與發送線程優先級高,實現快速處理掉接收數據*/ #define RT_LWIP_TCPTHREAD_MBOX_SIZE 10 /* TCP核心線程的使用的消息郵箱的大小,消息郵箱大能夠緩存更多的處理數據*/ #define RT_LWIP_TCPTHREAD_STACKSIZE 1024 /* TCP核心線程的堆棧大小 */ /* LWIP_NO_RX_THREAD is not set */ /* LWIP_NO_TX_THREAD is not set */ #define RT_LWIP_ETHTHREAD_PRIORITY 13 /* MAC層數據發送線程和接收線程的優先級 */ #define RT_LWIP_ETHTHREAD_STACKSIZE 1024 /* MAC層數據發送線程和接收線程的堆棧 */ #define RT_LWIP_ETHTHREAD_MBOX_SIZE 8 /* MAC層數據發送線程和接收線程的使用的郵箱大小,郵箱變大能夠緩存更多的以太網mac層數據 */ /* RT_LWIP_REASSEMBLY_FRAG is not set */ #define LWIP_NETIF_STATUS_CALLBACK 1 /* 使能網絡接口層的狀態回調函數功能 */ #define LWIP_NETIF_LINK_CALLBACK 1 /* 使能網絡接口層的link回調函數功能 */ #define SO_REUSE 1 /* 使能socket的SO_REUSEADDR功能,具體請見3.2節的功能介紹*/ #define LWIP_SO_RCVTIMEO 1 /* 使能接收超時功能,即調用接收函數recv, recvfrom能夠設置超時間時間,超時到了沒有數據返回錯誤*/ #define LWIP_SO_SNDTIMEO 1 /* 使能發送超時功能,即調用發送函數send, sendto能夠設置超時間時間,超時到了沒有數據返回錯誤*/ #define LWIP_SO_RCVBUF 1 /* 使能設置socket接收緩衝區在大小的功能選項*/ /* RT_LWIP_NETIF_LOOPBACK is not set */ #define LWIP_NETIF_LOOPBACK 0 /* 關閉環回網絡接口 */ /* RT_LWIP_STATS is not set */ /* RT_LWIP_USING_HW_CHECKSUM is not set */ /* 禁止硬件MAC層計算校驗和功能,採用軟件計算 */ #define RT_LWIP_USING_PING /* 使能網卡接口ping命令的功能 */ /* RT_LWIP_DEBUG is not set */ /* 禁止lwip協議內部的調試打印信息 */ /* end of light weight TCP/IP stack */
3.2 SO_REUSEADDR功能
通常來講,一個端口釋放後會等待兩分鐘2MSL的時間以後才能再被使用,SO_REUSEADDR是讓端口釋放後當即就能夠被再次使用。
SO_REUSEADDR
用於對TCP套接字處於TIME_WAIT狀態下的socket,才能夠重複綁定使用
server程序老是應該在調用bind()以前設置SO_REUSEADDR套接字選項
TCP,先調用close()的一方會進入TIME_WAIT狀態
SO_REUSEADDR提供以下四個功能:
- 容許啓動一個監聽服務器並捆綁其衆所周知端口,即便之前創建的將此端口用作他們的本地端口的鏈接仍存在。這一般是重啓監聽服務器時出現,若不設置此選項,則bind時將出錯
- 容許在同一端口上啓動同一服務器的多個實例,只要每一個實例捆綁一個不一樣的本地IP地址便可。對於TCP,咱們根本不可能啓動捆綁相同IP地址和相同端口號的多個服務器。
- 容許單個進程捆綁同一端口到多個套接口上,只要每一個捆綁指定不一樣的本地IP地址便可。這通常不用於TCP服務器。
- SO_REUSEADDR容許徹底重複的捆綁:
當一個IP地址和端口綁定到某個套接口上時,還容許此IP地址和端口捆綁到另外一個套接口上。通常來講,這個特性僅在支持多播的系統上纔有,並且只對UDP套接口而言(TCP不支持多播)
3.3 lwipopts.h配置文件
lwipopts.h頭文件用於對lwip協議的配置的用戶自定義部分。其中定義的配置宏比rtconfig.h中還要多一些,若是修改一些在rtconfig.h中沒有配置,能夠在此文件中修改。此文件中配置lwip協議的主要配置文件。
ifndef __LWIPOPTS_H__ #define __LWIPOPTS_H__ #include <rtconfig.h> #define ERRNO 1 #define LWIP_IPV4 1 #ifdef RT_USING_LWIP_IPV6 #define LWIP_IPV6 1 #else #define LWIP_IPV6 0 #endif /* RT_USING_LWIP_IPV6 */ #define NO_SYS 0 #define LWIP_SOCKET 1 #define LWIP_NETCONN 1 #ifdef RT_LWIP_IGMP #define LWIP_IGMP 1 #else #define LWIP_IGMP 0 #endif #ifdef RT_LWIP_ICMP #define LWIP_ICMP 1 #else #define LWIP_ICMP 0 #endif #ifdef RT_LWIP_SNMP #define LWIP_SNMP 1 #else #define LWIP_SNMP 0 #endif #ifdef RT_LWIP_DNS #define LWIP_DNS 1 #else #define LWIP_DNS 0 #endif #define LWIP_HAVE_LOOPIF 0 /*關閉環回接口,此宏用於設置本地環回接口的名稱爲localhost接口,打開環回功能時還要設置LWIP_NETIF_LOOPBACK 爲1*/ #define LWIP_PLATFORM_BYTESWAP 0 /*LWIP硬件平臺的字節順序交換功能,未被lwip協議代碼使用這個宏*/ #ifndef BYTE_ORDER #define BYTE_ORDER LITTLE_ENDIAN /*定義處理器的大端與小端功能,用於變換網絡字節順序與主機順序時使用*/ #endif /* #define RT_LWIP_DEBUG */ #ifdef RT_LWIP_DEBUG #define LWIP_DEBUG #endif /* ---------- Debug options ---------- */ #ifdef LWIP_DEBUG #ifdef RT_LWIP_SYS_DEBUG #define SYS_DEBUG LWIP_DBG_ON #else #define SYS_DEBUG LWIP_DBG_OFF #endif #ifdef RT_LWIP_ETHARP_DEBUG #define ETHARP_DEBUG LWIP_DBG_ON #else #define ETHARP_DEBUG LWIP_DBG_OFF #endif #ifdef RT_LWIP_PPP_DEBUG #define PPP_DEBUG LWIP_DBG_ON #else #define PPP_DEBUG LWIP_DBG_OFF #endif #ifdef RT_LWIP_MEM_DEBUG #define MEM_DEBUG LWIP_DBG_ON #else #define MEM_DEBUG LWIP_DBG_OFF #endif #ifdef RT_LWIP_MEMP_DEBUG #define MEMP_DEBUG LWIP_DBG_ON #else #define MEMP_DEBUG LWIP_DBG_OFF #endif #ifdef RT_LWIP_PBUF_DEBUG #define PBUF_DEBUG LWIP_DBG_ON #else #define PBUF_DEBUG LWIP_DBG_OFF #endif #ifdef RT_LWIP_API_LIB_DEBUG #define API_LIB_DEBUG LWIP_DBG_ON #else #define API_LIB_DEBUG LWIP_DBG_OFF #endif #ifdef RT_LWIP_API_MSG_DEBUG #define API_MSG_DEBUG LWIP_DBG_ON #else #define API_MSG_DEBUG LWIP_DBG_OFF #endif #ifdef RT_LWIP_TCPIP_DEBUG #define TCPIP_DEBUG LWIP_DBG_ON #else #define TCPIP_DEBUG LWIP_DBG_OFF #endif #ifdef RT_LWIP_NETIF_DEBUG #define NETIF_DEBUG LWIP_DBG_ON #else #define NETIF_DEBUG LWIP_DBG_OFF #endif #ifdef RT_LWIP_SOCKETS_DEBUG #define SOCKETS_DEBUG LWIP_DBG_ON #else #define SOCKETS_DEBUG LWIP_DBG_OFF #endif #ifdef RT_LWIP_DNS_DEBUG #define DNS_DEBUG LWIP_DBG_ON #else #define DNS_DEBUG LWIP_DBG_OFF #endif #ifdef RT_LWIP_AUTOIP_DEBUG #define AUTOIP_DEBUG LWIP_DBG_ON #else #define AUTOIP_DEBUG LWIP_DBG_OFF #endif #ifdef RT_LWIP_DHCP_DEBUG #define DHCP_DEBUG LWIP_DBG_ON #else #define DHCP_DEBUG LWIP_DBG_OFF #endif #ifdef RT_LWIP_IP_DEBUG #define IP_DEBUG LWIP_DBG_ON #else #define IP_DEBUG LWIP_DBG_OFF #endif #ifdef RT_LWIP_IP_REASS_DEBUG #define IP_REASS_DEBUG LWIP_DBG_ON #else #define IP_REASS_DEBUG LWIP_DBG_OFF #endif #ifdef RT_LWIP_ICMP_DEBUG #define ICMP_DEBUG LWIP_DBG_ON #else #define ICMP_DEBUG LWIP_DBG_OFF #endif #ifdef RT_LWIP_IGMP_DEBUG #define IGMP_DEBUG LWIP_DBG_ON #else #define IGMP_DEBUG LWIP_DBG_OFF #endif #ifdef RT_LWIP_UDP_DEBUG #define UDP_DEBUG LWIP_DBG_ON #else #define UDP_DEBUG LWIP_DBG_OFF #endif #ifdef RT_LWIP_TCP_DEBUG #define TCP_DEBUG LWIP_DBG_ON #else #define TCP_DEBUG LWIP_DBG_OFF #endif #ifdef RT_LWIP_TCP_INPUT_DEBUG #define TCP_INPUT_DEBUG LWIP_DBG_ON #else #define TCP_INPUT_DEBUG LWIP_DBG_OFF #endif #ifdef RT_LWIP_TCP_OUTPUT_DEBUG #define TCP_OUTPUT_DEBUG LWIP_DBG_ON #else #define TCP_OUTPUT_DEBUG LWIP_DBG_OFF #endif #ifdef RT_LWIP_TCP_RTO_DEBUG #define TCP_RTO_DEBUG LWIP_DBG_ON #else #define TCP_RTO_DEBUG LWIP_DBG_OFF #endif #ifdef RT_LWIP_TCP_CWND_DEBUG #define TCP_CWND_DEBUG LWIP_DBG_ON #else #define TCP_CWND_DEBUG LWIP_DBG_OFF #endif #ifdef RT_LWIP_TCP_WND_DEBUG #define TCP_WND_DEBUG LWIP_DBG_ON #else #define TCP_WND_DEBUG LWIP_DBG_OFF #endif #ifdef RT_LWIP_TCP_FR_DEBUG #define TCP_FR_DEBUG LWIP_DBG_ON #else #define TCP_FR_DEBUG LWIP_DBG_OFF #endif #ifdef RT_LWIP_TCP_QLEN_DEBUG #define TCP_QLEN_DEBUG LWIP_DBG_ON #else #define TCP_QLEN_DEBUG LWIP_DBG_OFF #endif #ifdef RT_LWIP_TCP_RST_DEBUG #define TCP_RST_DEBUG LWIP_DBG_ON #else #define TCP_RST_DEBUG LWIP_DBG_OFF #endif #endif /* LWIP_DEBUG */ #define LWIP_DBG_TYPES_ON (LWIP_DBG_ON|LWIP_DBG_TRACE|LWIP_DBG_STATE|LWIP_DBG_FRESH|LWIP_DBG_HALT) /* ---------- Memory options ---------- */ #define MEM_ALIGNMENT 4 /*動態內存堆中按4字節對齊 */ #define MEMP_OVERFLOW_CHECK 1 // /*使能內存池的溢出檢測功能 */ #define LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT 1 //// //#define MEM_LIBC_MALLOC 1 //#define MEM_USE_POOLS 1 //#define MEMP_USE_CUSTOM_POOLS 1 //#define MEM_SIZE (1024*64) #define MEMP_MEM_MALLOC 0 /* lwip的內存堆未使用協議自帶的,調用系統的動態內存堆*/ /* MEMP_NUM_PBUF: the number of memp struct pbufs. If the application sends a lot of data out of ROM (or other static memory), this should be set high. */ #define MEMP_NUM_PBUF 32 //16 /* the number of struct netconns */ #ifdef RT_MEMP_NUM_NETCONN #define MEMP_NUM_NETCONN RT_MEMP_NUM_NETCONN #endif /* the number of UDP protocol control blocks. One per active RAW "connection". */ #ifdef RT_LWIP_RAW_PCB_NUM #define MEMP_NUM_RAW_PCB RT_LWIP_RAW_PCB_NUM #endif /* the number of UDP protocol control blocks. One per active UDP "connection". */ #ifdef RT_LWIP_UDP_PCB_NUM #define MEMP_NUM_UDP_PCB RT_LWIP_UDP_PCB_NUM #endif /* the number of simulatenously active TCP connections. */ #ifdef RT_LWIP_TCP_PCB_NUM #define MEMP_NUM_TCP_PCB RT_LWIP_TCP_PCB_NUM #endif /* the number of simultaneously queued TCP */ #ifdef RT_LWIP_TCP_SEG_NUM #define MEMP_NUM_TCP_SEG RT_LWIP_TCP_SEG_NUM #else #define MEMP_NUM_TCP_SEG TCP_SND_QUEUELEN #endif /* * You can re-define following setting in rtcofnig.h to overwrite the default * setting in the lwip opts.h */ /* MEMP_NUM_NETBUF: the number of struct netbufs. */ // #define MEMP_NUM_NETBUF 2 /* MEMP_NUM_NETCONN: the number of struct netconns. */ // #define MEMP_NUM_NETCONN 4 /* MEMP_NUM_TCPIP_MSG_*: the number of struct tcpip_msg, which is used for sequential API communication and incoming packets. Used in src/api/tcpip.c. */ // #define MEMP_NUM_TCPIP_MSG_API 16 // #define MEMP_NUM_TCPIP_MSG_INPKT 16 /* ---------- Pbuf options ---------- */ /* PBUF_POOL_SIZE: the number of buffers in the pbuf pool. */ #ifdef RT_LWIP_PBUF_NUM #define PBUF_POOL_SIZE RT_LWIP_PBUF_NUM #endif /* PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. */ #ifdef RT_LWIP_PBUF_POOL_BUFSIZE #define PBUF_POOL_BUFSIZE RT_LWIP_PBUF_POOL_BUFSIZE #endif /* PBUF_LINK_HLEN: the number of bytes that should be allocated for a link level header. */ #define PBUF_LINK_HLEN 16 #ifdef RT_LWIP_ETH_PAD_SIZE #define ETH_PAD_SIZE RT_LWIP_ETH_PAD_SIZE #endif /** SYS_LIGHTWEIGHT_PROT * define SYS_LIGHTWEIGHT_PROT in lwipopts.h if you want inter-task protection * for certain critical regions during buffer allocation, deallocation and memory * allocation and deallocation. */ #define SYS_LIGHTWEIGHT_PROT (NO_SYS==0) /*使能關鍵的內存分配保護 */ #ifdef LWIP_USING_NAT #define IP_NAT 1 #else #define IP_NAT 0 #endif /* ---------- TCP options ---------- */ #ifdef RT_LWIP_TCP #define LWIP_TCP 1 #else #define LWIP_TCP 0 #endif #define TCP_TTL 255 /* Controls if TCP should queue segments that arrive out of order. Define to 0 if your device is low on memory. */ #define TCP_QUEUE_OOSEQ 1 /* TCP Maximum segment size. */ #define TCP_MSS 1460 /* 一個tcp段的大小 */ /* TCP sender buffer space (bytes). */ #ifdef RT_LWIP_TCP_SND_BUF #define TCP_SND_BUF RT_LWIP_TCP_SND_BUF #else #define TCP_SND_BUF (TCP_MSS * 2) #endif /* TCP sender buffer space (pbufs). This must be at least = 2 * TCP_SND_BUF/TCP_MSS for things to work. */ #define TCP_SND_QUEUELEN (4 * TCP_SND_BUF/TCP_MSS) /* TCP writable space (bytes). This must be less than or equal to TCP_SND_BUF. It is the amount of space which must be available in the tcp snd_buf for select to return writable */ #define TCP_SNDLOWAT (TCP_SND_BUF/2) #define TCP_SNDQUEUELOWAT TCP_SND_QUEUELEN/2 /* TCP receive window. */ #ifdef RT_LWIP_TCP_WND #define TCP_WND RT_LWIP_TCP_WND #else #define TCP_WND (TCP_MSS * 2) #endif /* Maximum number of retransmissions of data segments. */ #define TCP_MAXRTX 12 /* Maximum number of retransmissions of SYN segments. */ #define TCP_SYNMAXRTX 4 /* tcpip thread options */ #ifdef RT_LWIP_TCPTHREAD_PRIORITY #define TCPIP_MBOX_SIZE RT_LWIP_TCPTHREAD_MBOX_SIZE #define TCPIP_THREAD_PRIO RT_LWIP_TCPTHREAD_PRIORITY #define TCPIP_THREAD_STACKSIZE RT_LWIP_TCPTHREAD_STACKSIZE #else #define TCPIP_MBOX_SIZE 8 #define TCPIP_THREAD_PRIO 128 #define TCPIP_THREAD_STACKSIZE 4096 #endif #define TCPIP_THREAD_NAME "tcpip" /*tcp核心線程的名稱 */ #define DEFAULT_TCP_RECVMBOX_SIZE 10 /*tcp鏈接接收郵箱的大小*/ /* ---------- ARP options ---------- */ #define LWIP_ARP 1 /*使能ARP功能 */ #define ARP_TABLE_SIZE 10 /*ARP地址表的大小 */ #define ARP_QUEUEING 1 /* ARP隊列*/ /* ---------- Checksum options ---------- */ #ifdef RT_LWIP_USING_HW_CHECKSUM #define CHECKSUM_GEN_IP 0 #define CHECKSUM_GEN_UDP 0 #define CHECKSUM_GEN_TCP 0 #define CHECKSUM_GEN_ICMP 0 #define CHECKSUM_CHECK_IP 0 #define CHECKSUM_CHECK_UDP 0 #define CHECKSUM_CHECK_TCP 0 #define CHECKSUM_CHECK_ICMP 0 #endif /* ---------- IP options ---------- */ /* Define IP_FORWARD to 1 if you wish to have the ability to forward IP packets across network interfaces. If you are going to run lwIP on a device with only one network interface, define this to 0. */ #define IP_FORWARD 0 /* IP reassembly and segmentation.These are orthogonal even * if they both deal with IP fragments */ #ifdef RT_LWIP_REASSEMBLY_FRAG #define IP_REASSEMBLY 1 #define IP_FRAG 1 #define IP_REASS_MAX_PBUFS 10 #define MEMP_NUM_REASSDATA 10 #else #define IP_REASSEMBLY 0 #define IP_FRAG 0 #endif /* ---------- ICMP options ---------- */ #define ICMP_TTL 255 /* ---------- DHCP options ---------- */ /* Define LWIP_DHCP to 1 if you want DHCP configuration of interfaces. */ #ifdef RT_LWIP_DHCP #define LWIP_DHCP 1 #else #define LWIP_DHCP 0 #endif /* 1 if you want to do an ARP check on the offered address (recommended). */ #define DHCP_DOES_ARP_CHECK (LWIP_DHCP) /* ---------- AUTOIP options ------- */ #define LWIP_AUTOIP 0 #define LWIP_DHCP_AUTOIP_COOP (LWIP_DHCP && LWIP_AUTOIP) /* ---------- UDP options ---------- */ #ifdef RT_LWIP_UDP #define LWIP_UDP 1 #else #define LWIP_UDP 0 #endif #define LWIP_UDPLITE 0 #define UDP_TTL 255 #define DEFAULT_UDP_RECVMBOX_SIZE 1 /* UDP數據的接收的郵箱的大小 */ /* ---------- RAW options ---------- */ #ifdef RT_LWIP_RAW #define LWIP_RAW 1 #else #define LWIP_RAW 0 #endif #define DEFAULT_RAW_RECVMBOX_SIZE 1 /* RAW接收郵箱的大小 */ #define DEFAULT_ACCEPTMBOX_SIZE 10 /*accept函數的接收郵箱大小 */ /* ---------- Statistics options ---------- */ #ifdef RT_LWIP_STATS #define LWIP_STATS 1 #define LWIP_STATS_DISPLAY 1 #else #define LWIP_STATS 0 #endif #if LWIP_STATS #define LINK_STATS 1 #define IP_STATS 1 #define ICMP_STATS 1 #define IGMP_STATS 1 #define IPFRAG_STATS 1 #define UDP_STATS 1 #define TCP_STATS 1 #define MEM_STATS 1 #define MEMP_STATS 1 #define PBUF_STATS 1 #define SYS_STATS 1 #define MIB2_STATS 1 #endif /* LWIP_STATS */ /* ---------- PPP options ---------- */ #ifdef RT_LWIP_PPP /* 使能PPP協議*/ #define PPP_SUPPORT 1 /* Set > 0 for PPP */ #else #define PPP_SUPPORT 0 /* Set > 0 for PPP */ #endif #if PPP_SUPPORT #define NUM_PPP 1 /* Max PPP sessions. */ /* Select modules to enable. Ideally these would be set in the makefile but * we're limited by the command line length so you need to modify the settings * in this file. */ #ifdef RT_LWIP_PPPOE /*使能支持PPOE功能*/ #define PPPOE_SUPPORT 1 #else #define PPPOE_SUPPORT 0 #endif #ifdef RT_LWIP_PPPOS #define PPPOS_SUPPORT 1 #else #define PPPOS_SUPPORT 0 #endif /*如下爲ppp協議相關的配置*/ #define PAP_SUPPORT 1 /* Set > 0 for PAP. */ #define CHAP_SUPPORT 1 /* Set > 0 for CHAP. */ #define MSCHAP_SUPPORT 0 /* Set > 0 for MSCHAP (NOT FUNCTIONAL!) */ #define CBCP_SUPPORT 0 /* Set > 0 for CBCP (NOT FUNCTIONAL!) */ #define CCP_SUPPORT 0 /* Set > 0 for CCP (NOT FUNCTIONAL!) */ #define VJ_SUPPORT 1 /* Set > 0 for VJ header compression. */ #define MD5_SUPPORT 1 /* Set > 0 for MD5 (see also CHAP) */ #endif /* PPP_SUPPORT */ /** * LWIP_POSIX_SOCKETS_IO_NAMES==1: Enable POSIX-style sockets functions names. * Disable this option if you use a POSIX operating system that uses the same * names (read, write & close). (only used if you use sockets.c) */ #ifndef LWIP_POSIX_SOCKETS_IO_NAMES #define LWIP_POSIX_SOCKETS_IO_NAMES 0 #endif /** * LWIP_TCP_KEEPALIVE==1: Enable TCP_KEEPIDLE, TCP_KEEPINTVL and TCP_KEEPCNT * options processing. Note that TCP_KEEPIDLE and TCP_KEEPINTVL have to be set * in seconds. (does not require sockets.c, and will affect tcp.c) */ #ifndef LWIP_TCP_KEEPALIVE /*使能tcp連接的keepalive功能 此功能用於協議棧自動回收長時間沒有數據通訊的TCP鏈接,建議在tcp應用編程中開啓此功能*/ #define LWIP_TCP_KEEPALIVE 1 #endif /** * LWIP_NETIF_API==1: Support netif api (in netifapi.c) */ #ifndef LWIP_NETIF_API #define LWIP_NETIF_API 1 #endif #ifdef LWIP_IGMP #include <stdlib.h> #define LWIP_RAND rand #endif /* ------------------------------------ ---------- Socket options ---------- ------------------------------------ */ /* * LWIP_SOCKET==1: Enable Socket API (require to use sockets.c) */ #ifndef LWIP_SOCKET #define LWIP_SOCKET 1 #endif /* * LWIP_COMPAT_SOCKETS==1: Enable BSD-style sockets functions names. * (only used if you use sockets.c) */ #ifdef SAL_USING_POSIX #define LWIP_COMPAT_SOCKETS 0 #else #ifndef LWIP_COMPAT_SOCKETS #define LWIP_COMPAT_SOCKETS 1 #endif #endif /** * LWIP_SO_SNDTIMEO==1: Enable send timeout for sockets/netconns and * SO_SNDTIMEO processing. */ #ifndef LWIP_SO_SNDTIMEO #define LWIP_SO_SNDTIMEO 1 #endif /** * LWIP_SO_RCVTIMEO==1: Enable receive timeout for sockets/netconns and * SO_RCVTIMEO processing. */ #ifndef LWIP_SO_RCVTIMEO #define LWIP_SO_RCVTIMEO 1 #endif /** * LWIP_SO_RCVBUF==1: Enable SO_RCVBUF processing. */ #ifndef LWIP_SO_RCVBUF #define LWIP_SO_RCVBUF 1 #endif /** * If LWIP_SO_RCVBUF is used, this is the default value for recv_bufsize. */ #ifndef RECV_BUFSIZE_DEFAULT #define RECV_BUFSIZE_DEFAULT 8192 #endif /** * SO_REUSE==1: Enable SO_REUSEADDR option. */ #ifndef SO_REUSE /*請見3.2節的功能介紹說明 */ #define SO_REUSE 0 #endif /* ------------------------------------ ------- Applications options ------- ------------------------------------ */ /** * Max. length of TFTP filename */ #ifdef RT_LWIP_TFTP_MAX_FILENAME_LEN #define TFTP_MAX_FILENAME_LEN RT_LWIP_TFTP_MAX_FILENAME_LEN #elif defined(RT_DFS_ELM_MAX_LFN) #define TFTP_MAX_FILENAME_LEN RT_DFS_ELM_MAX_LFN #else #define TFTP_MAX_FILENAME_LEN 64 #endif /* Use the hostname*/ #define LWIP_NETIF_HOSTNAME 1 #endif /* __LWIPOPTS_H__ */
opt.h頭文件中定義了lwip協議的所有配置宏,都設置了默認的配置,若是在lwipopts.h,rtconfig.h中未定義的宏,將採用opt.h中的默認配置,若是想了解更全面的lwip配置請參考opt.h中的配置宏定義。
lwip配置中還有一個宏 LWIP_SO_LINGER,這個宏lwipopts.h中未使用定義,那麼lwip協議棧採用的是opt.h中默認配置,此配置是關閉的。這個功能有特殊的應用,具體以下文介紹。
3.4 LWIP_SO_LINGER做用
LWIP_SO_LINGER宏用於設置函數close()關閉TCP鏈接時的行爲。缺省close()的行爲是,若是有數據殘留在socket發送緩衝區中則系統將繼續發送這些數據給對方,等待被確認,而後返回。
利用此選項,能夠將此缺省行爲設置爲如下兩種
a.當即關閉該鏈接,經過發送RST分組(而不是用正常的FIN|ACK|FIN|ACK四個分組)來關閉該鏈接。至於發送緩衝區中若是有未發送完的數據,則丟棄。主動關閉一方的TCP狀態則跳過TIMEWAIT,直接進入CLOSED。網上不少人想利用這一點來解決服務器上出現大量的TIMEWAIT狀態的socket的問題,可是,這並非一個好主意,這種關閉方式的用途並不在這兒,實際用途在於服務器在應用層的需求。
b.將鏈接的關閉設置一個超時。若是socket發送緩衝區中仍殘留數據,進程進入睡眠,內核進入定時狀態去儘可能去發送這些數據。
在超時以前,若是全部數據都發送完且被對方確認,內核用正常的FIN|ACK|FIN|ACK四個分組來關閉該鏈接,close()成功返回。
若是超時之時,數據仍然未能成功發送及被確認,用上述a方式來關閉此鏈接。close()返回EWOULDBLOCK。
SO_LINGER選項使用以下結構:
struct linger {
int l_onoff;
int l_linger;
};
l_onoff爲0,則該選項關閉,l_linger的值被忽略,close()用上述缺省方式關閉鏈接。
l_onoff非0,l_linger爲0,close()用上述a方式關閉鏈接。
l_onoff非0,l_linger非0,close()用上述b方式關閉鏈接。 值得一說的是,無論你用什麼方式使用SO_LINGER,都須要大量耐心的測試來確保你的服務器程序確實是按照你的意願在跑,由於這個選項對服務器處理小量請求的行爲影響很是細微,簡單的功能測試很難驗證它的行爲,上線後量大的狀況下可能會出問題,讓你的服務器立刻下線,大併發量的模擬實際場景壓測才能保證其正確性:)