// 本文部份內容來自網絡html
1. 網絡基礎知識算法
OSI七層模型與TCP/IP模型對應關係編程
HTTPS與HTTPapi
HTTPS 協議的主要做用能夠分爲兩種:一種是創建一個信息安全通道,來保證數據傳輸的安全;另外一種就是確認網站的真實性。 HTTPS 和 HTTP 的區別主要以下:數組
SSL(Secure Sockets Layer 安全套接層)及其繼任者傳輸層安全(TransportLayer Security,TLS & Datagram Transport Layer Security,DTLS)是爲網絡通訊提供安全及數據完整性的一種安全協議。DTLS、TLS與SSL在傳輸層對網絡鏈接進行加密,DTLS在UDP傳輸協議之上,而SSL/TLS則在TCP傳輸協議之上。緩存
通常來講,HTTPS 主要用途有三個:一是經過證書等信息確認網站的真實性;二是創建加密的信息通道;三是數據內容的完整性。安全
SSL證書保證了網站的惟一性與真實性;服務器
簽發證書的 CA 中心會發布一種權威性的電子文檔——數字證書,它能夠經過加密技術(對稱加密與非對稱加密)對咱們在網上傳輸的信息進行加密。網絡
當數據包通過無數次路由器轉發後會發生數據劫持,黑客將數據劫持後進行篡改,好比植入廣告;開啓HTTPS後黑客就沒法對數據進行篡改,就算真的被篡改了,咱們也能夠檢測出問題數據結構
TCP報文格式
TCP封裝在IP報文中的時候,以下圖所示,TCP頭緊接着IP頭(IPV6有擴展頭的時候,則TCP頭在擴展頭後面),不攜帶選項(option)的TCP頭長爲20bytes,攜帶選項的TCP頭最長可到60bytes。
TCP的源端口、目的端口、以及IP層的源IP地址、目的IP地址四元組惟一的標識了一個TCP鏈接
TCP各字段釋義:
TCP源端口(Source Port):16位的源端口其中包含發送方應用程序對應的端口。源端口和源IP地址標示報文發送端的地址。
TCP目的端口(Destination port):16位的目的端口域定義傳輸的目的。這個端口指明報文接收計算機上的應用程序地址接口。
TCP序列號(SequenceNumber):32位的序列號標識了TCP報文中第一個byte在對應方向的傳輸中對應的字節序號。當SYN出現,SN=ISN(隨機值)單位是byte。好比發送端發送的一個TCP包淨荷(不包含TCP頭)爲12byte,SN爲5,則發送端接着發送的下一個數據包的時候,SN應該設置爲5+12=17。經過序列號,TCP接收端能夠識別出重複接收到的TCP包,從而丟棄重複包,同時對於亂序數據包也能夠依靠系列號進行重排序,進而對高層提供有序的數據流。另外若是接收的包中包含SYN或FIN標誌位,邏輯上也佔用1個byte,應答號需加1。
TCP應答號(Acknowledgment Number簡稱ACK Number):32位的ACK Number標識了報文發送端指望接收的字節序列。若是設置了ACK控制位,這個值表示一個準備接收的包的序列碼,注意是準備接收的包,好比當前接收端接收到一個淨荷爲12byte的數據包,SN爲5,則會回覆一個確認收到的數據包,若是這個數據包以前的數據也都已經收到了,這個數據包中的ACK Number則設置爲12+5=17,表示以前的數據都已經收到了,準備接受SN=17的數據包。
注:關於TCP序列號和應答號,也能夠參考文章:http://blog.csdn.net/a19881029/article/details/38091243/
頭長(Header Length):4位包括TCP頭大小,指示TCP頭的長度,即數據從何處開始。header length字段由4比特構成,最大值爲15,單位是32比特,即頭長的最大值爲15*32 bits = 60bytes,所以上面說攜帶選項的TCP頭長最長爲60bytes。
保留(Reserved):4位值域,這些位必須是0。爲了未來定義新的用途所保留,其中RFC3540將Reserved字段中的最後一位定義爲Nonce標誌。後續擁塞控制部分的講解咱們會簡單介紹Nonce標誌位。
標誌(Code Bits):8位標誌位,下面介紹。
窗口大小(Window Size):16位,該值指示了從Ack Number開始還願意接收多少byte的數據量,也即用來表示當前接收端的接收窗還有多少剩餘空間,用於TCP的流量控制。
校驗位(Checksum):16位TCP頭。發送端基於數據內容計算一個數值,接收端要與發送端數值結果徹底同樣,才能證實數據的有效性。接收端checksum校驗失敗的時候會直接丟掉這個數據包。CheckSum是根據僞頭+TCP頭+TCP數據三部分進行計算的。
優先指針(緊急,Urgent Pointer):16位,指向後面是優先數據的字節,在URG標誌設置了時纔有效。若是URG標誌沒有被設置,緊急域做爲填充。 選項(Option):長度不定,但長度必須以是32bits的整數倍。常見的選項包括MSS、SACK、Timestamp等等。
八位標誌位分別介紹以下:
CWR(Congestion Window Reduce):擁塞窗口減小標誌set by sender,用來代表它接收到了設置ECE標誌的TCP包。而且sender 在收到消息以後已經經過下降發送窗口的大小來下降發送速率。
ECE(ECN Echo):ECN響應標誌被用來在TCP3次握手時代表一個TCP端是具有ECN功能的。在數據傳輸過程當中也用來代表接收到的TCP包的IP頭部的ECN被設置爲11。注:IP頭部的ECN被設置爲11代表網絡線路擁堵。
注:關於CWR和ECE標記爲詳細信息可參考:http://www.cnblogs.com/hadis-yuki/p/5467787.html
URG(Urgent):該標誌位置位表示緊急(The urgent pointer) 標誌有效。該標誌位目前已經不多使用參考後面流量控制和窗口管理部分的介紹。
ACK:取值1表明Acknowledgment Number字段有效,這是一個確認的TCP包,取值0則不是確認包。後續文章介紹中當ACK標誌位有效的時候咱們稱呼這個包爲ACK包,使用大寫的ACK稱呼。
PSH(Push):該標誌置位時,通常是表示發送端緩存中已經沒有待發送的數據,接收端不將該數據進行隊列處理,而是儘量快將數據轉由應用處理。在處理 telnet 或 rlogin 等交互模式的鏈接時,該標誌老是置位的。
RST(Reset):用於reset相應的TCP鏈接。一般在發生異常或者錯誤的時候會觸發復位TCP鏈接。
SYN:同步序列編號(Synchronize Sequence Numbers)有效。該標誌僅在三次握手創建TCP鏈接時有效。
FIN(Finish):No more data from sender。當FIN標誌有效的時候咱們稱呼這個包爲FIN包。
UDP報文格式
u2字節源端口字段
源端口是一個大於1023的16位數字,由基於UDP應用程序的用戶進程隨機選擇。
u2字節節的端口字段
u2字節長度字段
指明瞭包括首部在內的UDP報文段長度。UDP長字段的值是UDP報文頭的長度(8字節)與UDP所攜帶數據長度的總和。
u2字節校驗和字段
是指整個UDP報文頭和UDP所帶的數據的校驗和(也包括僞報文頭)。僞報文頭不包括在真正的UDP報文頭中,可是它能夠保證UDP數據被正確的主機收到了。因在校驗和中加入了僞頭標,故ICMP除能防止單純數據差錯以外,對IP分組也具備保護做用。
源端口號和目的端口號如上和TCP的相同。
UDP長度:UDP報文的字節長度(包括首部和數據)。
UDP校驗和: 檢驗UDP首部和數據部分的正確性。
IP報文格式
版本:指IP協議的版本。
首部長度:首部的長度
服務類型:以下圖:
其中優先級用來區別優先級別不一樣的IP報文。 D表示要求有更低的時延。 T表示要求有更高的吞吐量。 R表示要求有更高的可靠性。
總長度:報文的長度。
標識:因爲數據報長度超過傳輸網絡的MTU(最大傳輸單元)而必須分片,這個標識字段的值被複制到全部數據報分片的標識字段中,使得這些分片在達到最終的目的地時能夠依照標識字段的內容從新組成原先的數據報。
標誌:最低位是MF,MF=1時,表示後面還有分片。中間位的DF,DF=1時,表示不能分片。
片偏移: 和前面的數據分片相關,是本分片在原先數據報文中相對首位的偏移位。
生存時間:數據報在網絡中存活的時間,所容許經過的路由器的最大數量,沒經過一個路由器,該值自動減一,若是數值爲0,路由器就能夠把該數據報丟棄。
協議: 指出數據報攜帶的數據是使用何種協議,以便目的主機的IP層能知道次數據報上交到哪個進程(不一樣協議有一個專門不一樣的進程處理)。
首部校驗位和:對首部進行校驗運算。校驗方法 : 在發送端,將IP數據報首部劃分爲多個16位的二進制序列,並將首部校驗和字段置爲0,用反碼運算將全部16位序列對位相加後,將獲得多的 和的反碼寫入首部校驗和字段。接收端接收到數據報後,將數據報首部的全部字段組織成多個16位的二進制序列,再使用反碼運算相加 一次,將獲得的結果取反。若是結果爲0表明沒出錯,不然出錯。
源地址:發送數據報的節點地址。
目的地址:接受數據報的節點地址。
ICMP協議
ICMP是網絡層的補充,能夠回送報文。用來檢測網絡是否通暢Ping命令就是發送ICMP的echo包,經過回送的echo relay進行網絡測試。
一臺擁有IP地址的主機能夠提供許多服務,好比Web服務、FTP服務、SMTP服務等,這些服務徹底能夠經過1個IP地址來實現。那麼,主機是怎樣區分不一樣的網絡服務呢?顯然不能只靠IP地址,由於IP 地址與網絡服務的關係是一對多的關係。其實是經過"IP地址+端口號"來區分不一樣的服務的。
服務器通常都是經過知名端口號來識別的,如圖2-2所示。例如,對於每一個TCP/IP實現來講,FTP服務器的TCP端口號都是21,每一個Telnet服務器的TCP端口號都是23,每一個TFTP(簡單文件傳送協議)服務器的UDP端口號都是69。任何TCP/IP實現所提供的服務都用知名的1~1023之間的端口號。這些知名端口號由Internet號分配機構(Internet Assigned Numbers Authority,IANA)來管理。
常見的應用層協議和傳輸層協議之間的關係:
Socket套接字接口參數
sock_stream 是有保障的(即能保證數據正確傳送到對方)面向鏈接的SOCKET,多用於資料(如文件)傳送。
sock_dgram 是無保障的面向消息的socket , 主要用於在網絡上發廣播信息。
SOCK_STREAM是基於TCP的,數據傳輸比較有保障。SOCK_DGRAM是基於UDP的,專門用於局域網,基於廣播SOCK_STREAM
是數據流,通常是tcp/ip協議的編程,SOCK_DGRAM分是數據抱,是udp協議網絡編程
AF_INET(又稱 PF_INET)是 IPv4 網絡協議的套接字類型,AF_INET6 則是 IPv6 的;而 AF_UNIX 則是 Unix 系統本地通訊。
選擇 AF_INET 的目的就是使用 IPv4 進行通訊。由於 IPv4 使用 32 位地址,相比 IPv6 的 128 位來講,計算更快,便於用於局域網通訊。
並且 AF_INET 相比 AF_UNIX 更具通用性,由於 Windows 上有 AF_INET 而沒有 AF_UNIX。
AF 表示ADDRESS FAMILY 地址族
PF 表示PROTOCL FAMILY 協議族
TCP三次握手
TCP是主機對主機層的傳輸控制協議,提供可靠的鏈接服務,採用三次握手確認創建一個鏈接:位碼即tcp標誌位,有6種標示:SYN(synchronous創建聯機) ACK(acknowledgement 確認) PSH(push傳送) FIN(finish結束) RST(reset重置) URG(urgent緊急)Sequence number(順序號碼) Acknowledge number(確認號碼)第一次握手:主機A發送位碼爲syn=1,隨機產生seq number=1234567的數據包到服務器,主機B由SYN=1知道,A要求創建聯機;第二次握手:主機B收到請求後要確認聯機信息,向A發送ack number=(主機A的seq+1),syn=1,ack=1,隨機產生seq=7654321的包;第三次握手:主機A收到後檢查ack number是否正確,即第一次發送的seq number+1,以及位碼ack是否爲1,若正確,主機A會再發送ack number=(主機B的seq+1),ack=1,主機B收到後確認seq值與ack=1則鏈接創建成功。
ARP MAC地址解析
數據包常常經過以太網發送,在發送數據包的過程當中先封裝IP的幀頭信息而後再封裝鏈路層的MAC地址,最後是以太網的幀頭信息。以太網的幀頭包括:目標地址、源地址、幀的類型,以太網設備的地址是48位的,它不識別32位的IP地址(IPV4)只識別MAC地址。由於以太網只識別設備的MAC地址,那麼問題就來了,源地址咱們是知道的就是主機A的MAC地址,那目標的MAC地址呢?咱們可能知道也可能不知道。怎樣獲得目標的MAC地址呢?地址解析協議會完成IP地址和MAC地址之間的映射獲得主機B的MAC地址,這是地址解析協議的絕活。
首先主機A根據路由表的內容肯定B主機的IP地址,而後在本主機上查詢ARP緩存的ARP表看看有沒有和B主機IP地址對應的MAC地址的歷史記錄,若是有就添加到以太網幀頭的目標地址。若是在ARP表中沒有與B主機IP對應的MAC地址,主機A就會向本地網絡中的全部主機廣播發送ARP請求幀(包含B主機的IP地址,A主機的IP地址和MAC地址),接收到ARP請求的各主機將收到的請求幀中的目標IP地址比較,若是與本身的IP地址不匹配丟棄ARP請求,若是B主機匹配B主機將本身的IP地址和MAC地址回覆給發送請求的A主機,同時B主機在ARP表中更新或者記錄主機A的IP地址和MAC地址。
A主機在收到數據時首先判斷幀的類型,能夠看到收到的數據多是IP數據也多是ARP數據。若是收到的是IP數據就會按IP的數據幀格式進行解算,若是收到的是ARP數據幀再判斷是響應幀仍是請求幀,若是是響應幀A主機就會更新本地的ARP表,如果請求幀就會把A主機的IP地址和MAC地址回覆給發送請求的主機
2. Zephry網絡架構
Zephyr經過合併Contiki RTOS開發了一個原生的、優化過的輕量級TCP/IP協議棧(名爲uIP,它實現了RFC兼容的IPv四、IPv六、TCP和UDP)。此外,Zephyr還包括一個完整的藍牙低功耗控制器和一個基於TinyCrypt的加密庫,以及支持MQTT和SSL。
######### http ############## ============================ http_client_send_req http_request http_send_flush http_send_msg_raw ######### net context ####### ============================== net_app_send_pkt ctx->send_data net_context_sendto sendto send_data ######### tcp/udp ####### ============================== net_tcp_send_head net_tcp_send_pkt ######### ip ####### ============================== net_send_data net_if_send_data iface->l2->send ######### l2(netif) ####### ============================== dummy_send net_if_queue_tx k_fifo_put(&iface->tx_queue, pkt) net_if_tx(k_fifo_get(&iface->tx_queue, K_NO_WAIT);) api->send xxx_tx(mdm) xxx_send_data xxx_msg_send_ceaselessly xxx_netif_msg_send ######### phy ####### ============================== icp_channel_send
net_context_get(AF_INET6, SOCK_DGRAM, IPPROTO_UDP, &context);
用於建立socket,信息保存在 struct net_context context 中
綁定本地端口(也可指定綁定IP)
net_context_bind(context, (struct sockaddr *)&my_addr6);
設置接收數據包接口
net_context_recv(context, udp_received, 0, &users_data);
指定接收函數爲udp_received,用戶提供。當收到外部發送來的數據包時,匹配IP及端口號後,內核從接收線程中調用udp_received。用戶根據不一樣狀況可有兩種選擇,當數據業務簡單且無阻塞操做時,可直接在接收線程中完成對數據包的解析工做。當數據業務複雜或者解析時有阻塞操做時,則應該將數據包傳遞給應用線程去作,該回調僅僅做爲數據傳遞使用。傳遞數據包可參考使用全局變量、內核提供的鏈表、fifo、mailbox、ringbuffer等,也可用戶自行決定方式。
獲取發送數據包
send_pkt = net_pkt_get_tx(context, K_FOREVER);
獲取數據包管理結構
net_pkt_get_data
獲取數據data
net_pkt_append_all(send_pkt, expecting_len, data,K_FOREVER);
將數據data拷貝到數據包中struct net_pkt * send_pkt中
net_context_sendto(send_pkt, &dst_addr,addrlen, udp_sent, 0, len, proto);
釋放socket
net_context_put(context);
struct net_context *context;
net_context_get(AF_INET, SOCK_STREAM, IPPROTO_TCP,tcp_recv4);
用於建立socket,信息保存在 struct net_context tcp_recv4中
綁定本地端口和IP
net_context_bind(*tcp_recv4,(struct sockaddr *)&my_addr4, sizeof(struct sockaddr_in));
調用tcp鏈接接口
net_context_connect(tcp_send,(struct sockaddr *)&peer_addr4,
sizeof(peer_addr4),tcp_connected,K_FOREVER,UINT_TO_POINTER(AF_INET));
若鏈接成功,內核會返回成功值並調用tcp_connected接口通知已經建鏈。
設置接收數據包接口
net_context_recv(tcp, cb, 0, user_data);
在net_context_connect成功後調用,推薦在tcp_connected中設置。原理同4.3.
獲取發送數據包
send_pkt = net_pkt_get_tx(context, K_FOREVER);
獲取數據包管理結構
send_frag = net_pkt_get_data(context, K_FOREVER);
獲取數據data
net_pkt_frag_add(send_pkt, send_frag);
將數據data信息插入pkt
net_pkt_append_all(send_pkt, expecting_len, data,K_FOREVER);
將數據data拷貝到數據包中struct net_pkt * send_pkt中
發送數據包接口
net_context_send(send_pkt, tcp_sent, 0, len, proto);
釋放socket
net_context_put(context);
net_pkt_get_data最終調用內存管理接口申請內存:
net_pkt_get_data _pkt_get_data net_pkt_get_reserve_data net_pkt_get_reserve_data net_buf_alloc net_buf_alloc_len data_alloc pool->alloc->cb->alloc(buf, size, timeout) heap_data_alloc #define net_buf_alloc(_pool, _timeout) net_buf_alloc_len(_pool, CONFIG_NET_BUF_DATA_SIZE ,_timeout); #define CONFIG_NET_BUF_DATA_SIZE 128 也就是說,每次申請數據data的buffer都是固定128字節大小
net_pkt_append_all net_pkt_append net_pkt_append_bytes static inline u16_t net_pkt_append_bytes(struct net_pkt *pkt, const u8_t *value, u16_t len, s32_t timeout) { struct net_buf *frag = net_buf_frag_last(pkt->frags); u16_t added_len = 0; do { u16_t count = min(len, net_buf_tailroom(frag)); void *data = net_buf_add(frag, count); memcpy(data, value, count); len -= count; added_len += count; value += count; if (len == 0) { return added_len; } frag = net_pkt_get_frag(pkt, timeout); if (!frag) { return added_len; } net_pkt_frag_add(pkt, frag); } while (1); /* Unreachable */ return 0; }
net_context_connect:完成TCP三次握手,最終創建鏈接
1.net_tcp_register註冊接收到ack包後的回調接口
ret = net_tcp_register(addr,
laddr,
ntohs(rport),
ntohs(lport),
tcp_synack_received,
context,
&context->conn_handler);
2. 發送syn包
send_syn(context, addr);
3. 收到ack包後進入tcp_synack_received函數,該函數首先註冊收到數據後的回調接口tcp_established,而後發送ack包
ret = net_tcp_register(&remote_addr,
&local_addr,
ntohs(tcp_hdr->src_port),
ntohs(tcp_hdr->dst_port),
tcp_established,
context,
&context->conn_handler);
send_ack(context, &remote_addr, false);
相關配置
socket相關的總鏈接個數(TCP+UDP+ICMP等鏈接總個數):
CONFIG_NET_MAX_CONN TCPIP鏈接管理結構體conn個數
CONFIG_NET_MAX_CONTEXTS 對接socket的context個數
說明:如須要修改鏈接個數,這兩個值都要修改,並且個數要一致。Dns功能須要佔用一個鏈接,因此留給客戶可以使用的鏈接個數爲「CONFIG_NET_MAX_CONTEXTS-1」。
POLL個數:
CONFIG_NET_SOCKETS_POLL_MAX socket poll的個數,必須大於等於應用用的poll的個數,且不能大於「總鏈接個數」
TCP服務端鏈接個數 :
CONFIG_NET_TCP_BACKLOG_SIZE tcp服務端管理數組,必須大於等於tcp當服務端的鏈接
TCP時間配置
CONFIG_NET_SOCKETS_CONNECT_TIMEOUT tcp鏈接超時時間,單位秒。超過該時間tcp握手鍊接失敗
CONFIG_NET_TCP_ACK_TIMEOUT 等待對端ACK的超時時間。用於作服務端發送SYN_ACK後等對端ACK,正常狀況關閉過程FIN等待對端ACK。 CONFIG_NET_TCP_INIT_RETRANSMISSION_TIMEOUT tcp首次重傳時間,之後重傳時間每次會翻倍。修改此值會減少因爲網絡慢致使的重傳次數過多,適用於網絡延時大的狀況。該值能夠經過NV配置,如:「AT+ZNVSET="tcp_retran_time",2000」,表示首次重傳時間爲2000毫秒,該功能重啓生效。
CONFIG_NET_TCP_RETRY_COUNT tcp重傳次數,超過該重傳次數內核會斷開鏈接
內存使用上限配置相關
CONFIG_NET_PKT_RX_COUNT 接收數據包頭緩存個數 決定能夠緩存多少個IP包
CONFIG_NET_PKT_TX_COUNT 發送數據包頭緩存個數
CONFIG_NET_BUF_RX_COUNT 接收數據包數據段個數 決定能夠緩存多少個IP數據包數據段,每一個大小爲CONFIG_NET_BUF_DATA_SIZE
CONFIG_NET_BUF_TX_COUNT 發送數據包數據段個數
CONFIG_NET_BUF_DATA_SIZE 每一個數據包數據段的大小 單個IP數據包數據段的大小
修改原則:
發送多包小數據,改大CONFIG_NET_PKT_TX_COUNT;
接收多包小數據,改大CONFIG_NET_PKT_RX_COUNT。
發送少包大數據,改大CONFIG_NET_BUF_TX_COUNT;
接收少包大數據,改大CONFIG_NET_BUF_RX_COUNT。
發送多包大數據,改大CONFIG_NET_PKT_TX_COUNT和CONFIG_NET_BUF_TX_COUNT;
接收大包大數據,改大CONFIG_NET_PKT_RX_COUNT和CONFIG_NET_BUF_RX_COUNT。
改小的狀況請以此類推。
高層協議指TCP\UDP之上的協議,有時應用傳輸數據時,會在底層協議之上加載上層協議,好比http、caop等。有時,高層協議會提供socket封裝接口,向用戶屏蔽socket層的具體調用實現,不一樣的操做系統狀況不同,在zephyr中,http接口實現了該類封裝,當須要使用socket向外發送數據時,只需調用
http_client_init(&http_ctx, SERVER_ADDR, SERVER_PORT);便可,socket由該接口自動建立並供用戶使用。發送數據調http_client_send_req(ctx, &req, NULL, result, sizeof(result),NULL, APP_REQ_TIMEOUT);便可
coap協議並無提供這樣的封裝接口,須要按標準方式調用。
主要接口函數:
int http_client_init(struct http_ctx *ctx,
const char *server,
u16_t server_port,
struct sockaddr *server_addr,
s32_t timeout);
發送數據前,先經過http_client_init()初始化http client,ctx是當前http連接的上下文;server是字符串形式的服務器ip地址或域名(傳入域名時必須保證dns解析可用);server_port是服務器監聽的端口;server_addr是struct sockaddr形式的ip地址,能夠爲NULL,爲NULL時將使用server做爲服務器地址;timeout是域名解析的超時時間。
int http_client_send_req(struct http_ctx *ctx,
struct http_request *req,
http_response_cb_t cb,
u8_t *response_buf,
size_t response_buf_len,
void *user_data,
s32_t timeout);
使用http_client_send_req()發送數據,ctx是當前http連接的上下文;req是發送請求的具體信息和數據(數據結構見上面的重要結構體);cb是應用接收返回的數據的回調;response_buf是應用接收數據存放的空間,須要應用提早申請好空間;response_buf_len是response_buf的長度;user_data設爲NULL;timeout是等待服務器回覆的超時時間。注意這裏的cb是應用主要處理服務器返回的數據的函數,須要應用根據其業務實現。
int net_app_close(struct net_app_ctx *ctx);
釋放http連接,ctx是當前net_app連接的上下文,struct http_ctx中有這個struct net_app_ctx。
Accept、Accept-Charset、Accept-Encoding、Accept-language,這些項直接填到struct http_request 中的header_fields裏,應用本身解析所指示的可接受的數據內容、字符集、編碼方式、語言等。服務器返回的 status code 直接傳給應用,由應用來判斷成功仍是失敗。對於30一、302等重定向的返回碼,由應用來處理
http接口中對Socket的封裝 http_client_init net_app_init_tcp_client net_app_init_client _net_app_config_local_ctx setup_ipv4_ctx net_context_get bind_local _net_app_set_net_ctx net_context_bind /* TCP recv callback is set after we have accepted the* connection.*/ http_client_send_req net_app_connect http_request http_prepare_and_send get_net_pkt net_app_get_net_pkt_with_dst net_pkt_get_tx net_pkt_append net_pkt_get_frag net_pkt_get_reserve_data net_pkt_frag_add
TLS 創建於TCP可靠的傳輸機制之上,而DTLS基於UDP,必須自建保障機制: DTLS 必須檢測MTU大小,當應用層數據包超過期報錯; 爲防止握手的IP數據包超載致使丟失,DTLS 針對握手消息實現fragment處理。
TLS 在傳輸出錯時會中斷鏈接,而DTLS需兼容多種出錯場景,出錯時每每直接丟棄處理;