欧美成人午夜精品久久久,国产?V天堂一区二区三区,欧美精品va在线观看,亚洲一区二区三区免费在线观看,av无码精品一区二区久久,欧美性爱视频不卡一区三区,欧美乱人伦视频在线观看,国产一级牲交高潮

ARTICLE DETAIL

資訊詳情

深耕商務(wù)建站與企業(yè)官網(wǎng)運(yùn)營(yíng)的一線實(shí)戰(zhàn)洞察。

TCP粘包拆包解決方案:長(zhǎng)度前綴法協(xié)議設(shè)計(jì)與C/C++實(shí)現(xiàn)

TCP粘包拆包解決方案:長(zhǎng)度前綴法協(xié)議設(shè)計(jì)與C/C++實(shí)現(xiàn) 1. 項(xiàng)目概述從字節(jié)流到消息幀的鴻溝搞過(guò)C/C網(wǎng)絡(luò)編程的朋友尤其是做服務(wù)端開(kāi)發(fā)的十有八九都踩過(guò)TCP粘包和拆包的坑。這玩意兒就像你網(wǎng)購(gòu)了一箱樂(lè)高賣家發(fā)過(guò)來(lái)一個(gè)巨大的麻袋里面所有零件都混在一起說(shuō)明書(shū)也揉成一團(tuán)塞在里面。你的任務(wù)是把它們一個(gè)個(gè)拼成完整的模型但麻袋本身不告訴你哪里是一個(gè)模型的開(kāi)始哪里是結(jié)束。TCP協(xié)議就是這個(gè)“麻袋”它只保證把一堆字節(jié)樂(lè)高零件按順序、可靠地送到你手里至于這一堆字節(jié)里包含了幾個(gè)完整的“消息”樂(lè)高模型以及每個(gè)消息的邊界在哪它一概不管。這就是所謂的“基于字節(jié)流”的傳輸特性。因此“粘包”和“拆包”就成了我們必須面對(duì)的應(yīng)用層問(wèn)題。粘包就是發(fā)送方連續(xù)發(fā)出的多個(gè)小數(shù)據(jù)包被接收方一次性收到了像粘在了一起拆包則是一個(gè)大的數(shù)據(jù)包被TCP底層拆分成多個(gè)小包到達(dá)或者一個(gè)包的后半部分和下一個(gè)包的前半部分粘在一起到達(dá)。不解決這個(gè)問(wèn)題你的程序就永遠(yuǎn)無(wú)法正確解析出對(duì)方發(fā)來(lái)的完整請(qǐng)求服務(wù)也就無(wú)從談起。今天要聊的“長(zhǎng)度前綴法”就是解決這個(gè)問(wèn)題的經(jīng)典且高效的方案它相當(dāng)于在每個(gè)樂(lè)高模型盒子外面先貼上一個(gè)標(biāo)簽寫(xiě)明里面有多少塊零件。2. 核心原理為什么長(zhǎng)度前綴是治本之策要解決問(wèn)題得先理解問(wèn)題的根源。TCP粘包/拆包不是Bug而是由其設(shè)計(jì)特性決定的必然現(xiàn)象。發(fā)送端應(yīng)用程序調(diào)用send或write將數(shù)據(jù)交給TCP發(fā)送緩沖區(qū)TCP協(xié)議棧會(huì)根據(jù)MSS最大報(bào)文段長(zhǎng)度、擁塞窗口、Nagle算法等因素決定如何將緩沖區(qū)中的數(shù)據(jù)封裝成多個(gè)TCP報(bào)文段發(fā)送出去。接收端的TCP協(xié)議棧則按序?qū)⒔邮盏降膱?bào)文段數(shù)據(jù)放入接收緩沖區(qū)應(yīng)用程序通過(guò)recv或read從緩沖區(qū)中讀取數(shù)據(jù)。關(guān)鍵點(diǎn)在于應(yīng)用程序的“寫(xiě)”和“讀”的單元與TCP協(xié)議棧“發(fā)”和“收”的單元是完全解耦的。這就引出了解決思路的核心我們需要在應(yīng)用層自己定義“消息”的邊界。常見(jiàn)的方法有固定長(zhǎng)度每個(gè)消息都一樣長(zhǎng)不足補(bǔ)位。簡(jiǎn)單但浪費(fèi)帶寬不靈活。特殊分隔符比如用\n或\0作為消息結(jié)束標(biāo)志。但消息體本身如果包含分隔符就需要轉(zhuǎn)義處理稍麻煩。長(zhǎng)度前綴在消息體前面先發(fā)送一個(gè)固定長(zhǎng)度的字段用來(lái)表示后續(xù)消息體的長(zhǎng)度。這是最常用、最可靠的方法。為什么長(zhǎng)度前綴法備受青睞因?yàn)樗逦?、無(wú)歧義、效率高。接收方只需要先讀取固定長(zhǎng)度的長(zhǎng)度字段就能確切地知道接下來(lái)還要讀取多少字節(jié)才能構(gòu)成一個(gè)完整的應(yīng)用層消息。無(wú)論底層TCP如何拆包粘包只要我能按長(zhǎng)度準(zhǔn)確讀取就能完美重組消息。這就像快遞單號(hào)你不需要知道包裹被分成了幾輛車運(yùn)輸只要憑單號(hào)就能收齊所有部件。2.1 長(zhǎng)度字段的設(shè)計(jì)考量長(zhǎng)度前綴本身也是一個(gè)需要設(shè)計(jì)的數(shù)據(jù)。主要考慮兩個(gè)問(wèn)題多長(zhǎng)什么字節(jié)序長(zhǎng)度字段的字節(jié)數(shù)通常使用1字節(jié)、2字節(jié)或4字節(jié)的無(wú)符號(hào)整數(shù)。1字節(jié)0-255太短只能傳遞很小的消息2字節(jié)0-65535對(duì)于大多數(shù)控制命令和短消息夠用4字節(jié)約42億則幾乎可以應(yīng)對(duì)所有場(chǎng)景。在通用網(wǎng)絡(luò)編程中我強(qiáng)烈推薦使用4字節(jié)uint32_t一勞永逸避免未來(lái)因消息體增長(zhǎng)而重構(gòu)協(xié)議。多出的2個(gè)字節(jié)在當(dāng)今網(wǎng)絡(luò)帶寬下開(kāi)銷微乎其微。字節(jié)序Endianness問(wèn)題這是網(wǎng)絡(luò)編程的經(jīng)典坑。不同的CPU架構(gòu)如x86用小端序某些網(wǎng)絡(luò)設(shè)備可能用大端序?qū)Χ嘧止?jié)整數(shù)的內(nèi)存存儲(chǔ)方式不同。為了保證發(fā)送方和接收方對(duì)長(zhǎng)度值的解讀一致必須約定網(wǎng)絡(luò)傳輸?shù)淖止?jié)序。行業(yè)標(biāo)準(zhǔn)是使用網(wǎng)絡(luò)字節(jié)序大端序。發(fā)送前用htonl()將主機(jī)序轉(zhuǎn)為網(wǎng)絡(luò)序接收后用ntohl()轉(zhuǎn)回主機(jī)序。// 發(fā)送端示例構(gòu)造帶4字節(jié)長(zhǎng)度前綴的消息 void send_message(int sockfd, const char* data, uint32_t len) { uint32_t net_len htonl(len); // 轉(zhuǎn)換為主機(jī)序到網(wǎng)絡(luò)序 // 先發(fā)送長(zhǎng)度前綴 send(sockfd, net_len, sizeof(net_len), 0); // 再發(fā)送消息體 send(sockfd, data, len, 0); }注意這里為了演示分兩次調(diào)用send但在實(shí)際高并發(fā)場(chǎng)景下這可能導(dǎo)致“寫(xiě)一半”的情況即長(zhǎng)度前綴和消息體被拆分成兩個(gè)TCP包。更優(yōu)的做法是使用writev系統(tǒng)調(diào)用或先將數(shù)據(jù)拼接在用戶態(tài)緩沖區(qū)再一次性發(fā)送。下文會(huì)詳細(xì)討論。3. 協(xié)議設(shè)計(jì)與數(shù)據(jù)包結(jié)構(gòu)一個(gè)健壯的、基于長(zhǎng)度前綴的應(yīng)用層協(xié)議其數(shù)據(jù)包結(jié)構(gòu)非常簡(jiǎn)單清晰---------------------------------------- | 長(zhǎng)度字段 (4字節(jié)) | 消息體 (N字節(jié)) | ----------------------------------------這個(gè)簡(jiǎn)單的結(jié)構(gòu)卻需要嚴(yán)謹(jǐn)?shù)拇a來(lái)實(shí)現(xiàn)收發(fā)邏輯。我們先定義協(xié)議頭// protocol.h #ifndef PROTOCOL_H #define PROTOCOL_H #include stdint.h // 為了使用 uint32_t // 協(xié)議頭固定4字節(jié)存儲(chǔ)消息體長(zhǎng)度網(wǎng)絡(luò)字節(jié)序 typedef struct { uint32_t bodyLength; // 消息體長(zhǎng)度 } ProtocolHeader; // 計(jì)算整個(gè)數(shù)據(jù)包的長(zhǎng)度頭部體部 #define PACKET_LENGTH(body_len) (sizeof(ProtocolHeader) (body_len)) // 常用的輔助函數(shù)聲明 uint32_t parse_header(const char* data); void build_header(char* buffer, uint32_t body_len); #endif // PROTOCOL_H協(xié)議頭的實(shí)現(xiàn)// protocol.c #include “protocol.h” #include arpa/inet.h // 為了使用 htonl, ntohl uint32_t parse_header(const char* data) { // 假設(shè) data 指向一個(gè)完整的 ProtocolHeader 結(jié)構(gòu) const ProtocolHeader* header (const ProtocolHeader*)data; // 將網(wǎng)絡(luò)字節(jié)序轉(zhuǎn)換為主機(jī)字節(jié)序 return ntohl(header-bodyLength); } void build_header(char* buffer, uint32_t body_len) { ProtocolHeader* header (ProtocolHeader*)buffer; header-bodyLength htonl(body_len); // 轉(zhuǎn)換為主機(jī)序到網(wǎng)絡(luò)序 }3.1 消息的封裝與發(fā)送發(fā)送消息不是簡(jiǎn)單調(diào)用兩次send。我們必須考慮“原子性”即希望接收方要么收到完整的數(shù)據(jù)包長(zhǎng)度前綴消息體要么完全收不到。雖然TCP是可靠協(xié)議但無(wú)法保證應(yīng)用層多次send的數(shù)據(jù)在接收方的一次recv中收到。因此優(yōu)化發(fā)送策略至關(guān)重要。方案一使用內(nèi)存緩沖區(qū)拼接后一次性發(fā)送這是最推薦的方法尤其對(duì)于短消息。它減少了系統(tǒng)調(diào)用的次數(shù)也避免了TCP Nagle算法與延遲確認(rèn)Delayed ACK可能引起的交互延遲問(wèn)題。// sender.c - 優(yōu)化后的發(fā)送函數(shù) #include stdlib.h #include string.h #include unistd.h #include “protocol.h” int send_packet(int fd, const char* body, uint32_t body_len) { // 1. 計(jì)算總長(zhǎng)度并分配緩沖區(qū) uint32_t total_len PACKET_LENGTH(body_len); char* packet (char*)malloc(total_len); if (!packet) return -1; // 分配失敗 // 2. 構(gòu)建協(xié)議頭 build_header(packet, body_len); // 3. 拷貝消息體 memcpy(packet sizeof(ProtocolHeader), body, body_len); // 4. 一次性發(fā)送整個(gè)數(shù)據(jù)包 ssize_t sent write(fd, packet, total_len); free(packet); if (sent ! total_len) { // 處理發(fā)送不完全的情況如EINTR、EAGAIN錯(cuò)誤 return -1; } return 0; }方案二使用 writev 進(jìn)行向量化寫(xiě)操作如果消息體本身已經(jīng)存在于某個(gè)緩沖區(qū)比如文件映射的內(nèi)存為了避免額外的內(nèi)存拷貝可以使用writev系統(tǒng)調(diào)用它允許將多個(gè)不連續(xù)的內(nèi)存塊在一次系統(tǒng)調(diào)用中發(fā)送出去。#include sys/uio.h // 為了使用 struct iovec int send_packet_v(int fd, const char* body, uint32_t body_len) { ProtocolHeader header; header.bodyLength htonl(body_len); struct iovec iov[2]; iov[0].iov_base header; iov[0].iov_len sizeof(header); iov[1].iov_base (void*)body; // 注意去掉const限定 iov[1].iov_len body_len; ssize_t sent writev(fd, iov, 2); return (sent sizeof(header) body_len) ? 0 : -1; }實(shí)操心得在追求極致性能的場(chǎng)景下writev可以減少一次內(nèi)存拷貝但它的可讀性稍差且需要處理const轉(zhuǎn)換。對(duì)于大多數(shù)業(yè)務(wù)場(chǎng)景第一種方法內(nèi)存拼接因其簡(jiǎn)單直觀而更常用。務(wù)必記住不要連續(xù)調(diào)用send(fd, len, 4, 0); send(fd, body, len, 0);這在高并發(fā)下是粘包問(wèn)題的“制造者”而非解決者。4. 接收與解包狀態(tài)機(jī)解析法接收端是粘包/拆包處理的核心和難點(diǎn)。因?yàn)閿?shù)據(jù)是流式的我們可能在任何時(shí)候收到任意長(zhǎng)度的字節(jié)。一個(gè)健壯的接收器必須是一個(gè)狀態(tài)機(jī)它維護(hù)當(dāng)前的解析狀態(tài)。通常有兩種狀態(tài)正在讀取長(zhǎng)度頭狀態(tài)正在讀取消息體狀態(tài)同時(shí)我們需要一個(gè)緩沖區(qū)來(lái)存儲(chǔ)不完整的數(shù)據(jù)即“半包”數(shù)據(jù)。4.1 環(huán)形緩沖區(qū) vs 預(yù)分配緩沖區(qū)管理這個(gè)緩沖區(qū)有兩種主流方式預(yù)分配固定大小緩沖區(qū)為每個(gè)連接分配一個(gè)足夠大的緩沖區(qū)比如4KB或16KB。邏輯簡(jiǎn)單但如果消息大小差異巨大會(huì)造成內(nèi)存浪費(fèi)或需要?jiǎng)討B(tài)調(diào)整。環(huán)形緩沖區(qū)更高效地利用內(nèi)存適合高性能轉(zhuǎn)發(fā)場(chǎng)景但實(shí)現(xiàn)稍復(fù)雜。這里我們展示一個(gè)使用預(yù)分配緩沖區(qū)的經(jīng)典實(shí)現(xiàn)。我們?yōu)槊總€(gè)TCP連接用一個(gè)Connection結(jié)構(gòu)體表示維護(hù)其讀狀態(tài)。// connection.h #ifndef CONNECTION_H #define CONNECTION_H #include stdint.h #define READ_BUFFER_SIZE 4096 #define MAX_PACKET_SIZE (1024 * 1024) // 定義最大允許的消息體大小防止惡意攻擊 typedef enum { READ_STATE_HEADER, // 正在讀取頭部 READ_STATE_BODY // 正在讀取消息體 } ReadState; typedef struct { int fd; // 套接字描述符 ReadState state; // 當(dāng)前讀取狀態(tài) char read_buf[READ_BUFFER_SIZE]; // 讀緩沖區(qū) uint32_t read_idx; // 緩沖區(qū)中已有數(shù)據(jù)的下一個(gè)寫(xiě)入位置 uint32_t parsed_idx; // 緩沖區(qū)中已解析數(shù)據(jù)的位置 // 當(dāng)前正在解析的包的信息 uint32_t expected_body_len; // 期望的消息體長(zhǎng)度 uint32_t recvd_body_len; // 已接收的消息體長(zhǎng)度 } Connection; // 初始化連接結(jié)構(gòu) void conn_init(Connection* conn, int fd); // 處理可讀事件返回處理完的完整數(shù)據(jù)包數(shù) int conn_handle_read(Connection* conn); #endif // CONNECTION_H4.2 接收狀態(tài)機(jī)的核心邏輯conn_handle_read函數(shù)是狀態(tài)機(jī)的驅(qū)動(dòng)引擎它需要被事件循環(huán)如select、poll、epoll在套接字可讀時(shí)調(diào)用。// connection.c #include “connection.h” #include “protocol.h” #include unistd.h #include errno.h #include stdio.h #include string.h #include arpa/inet.h void conn_init(Connection* conn, int fd) { conn-fd fd; conn-state READ_STATE_HEADER; conn-read_idx 0; conn-parsed_idx 0; conn-expected_body_len 0; conn-recvd_body_len 0; memset(conn-read_buf, 0, READ_BUFFER_SIZE); } // 從socket讀取數(shù)據(jù)到應(yīng)用層緩沖區(qū) static int read_socket(Connection* conn) { // 計(jì)算緩沖區(qū)剩余空間 size_t avail READ_BUFFER_SIZE - conn-read_idx; if (avail 0) { // 緩沖區(qū)已滿但還沒(méi)解析出一個(gè)完整包說(shuō)明包太大或協(xié)議異常 return -1; } ssize_t n read(conn-fd, conn-read_buf conn-read_idx, avail); if (n 0) { if (errno EINTR || errno EAGAIN || errno EWOULDBLOCK) { return 0; // 非致命錯(cuò)誤下次再試 } return -1; // 真正的讀錯(cuò)誤 } else if (n 0) { return -1; // 對(duì)端關(guān)閉連接 } conn-read_idx n; return 1; // 成功讀取到數(shù)據(jù) } // 從應(yīng)用層緩沖區(qū)解析數(shù)據(jù) static int parse_buffer(Connection* conn) { int packet_count 0; // 只要緩沖區(qū)里有數(shù)據(jù)且能解析就持續(xù)解析 while (conn-parsed_idx conn-read_idx) { if (conn-state READ_STATE_HEADER) { // 檢查是否夠一個(gè)協(xié)議頭 if (conn-read_idx - conn-parsed_idx sizeof(ProtocolHeader)) { break; // 頭部數(shù)據(jù)還不完整等待下次讀取 } // 解析出消息體長(zhǎng)度 conn-expected_body_len parse_header(conn-read_buf conn-parsed_idx); conn-parsed_idx sizeof(ProtocolHeader); // 安全性檢查長(zhǎng)度是否合法 if (conn-expected_body_len MAX_PACKET_SIZE) { fprintf(stderr, “Error: Packet body too large: %u\n”, conn-expected_body_len); return -1; } conn-state READ_STATE_BODY; conn-recvd_body_len 0; } if (conn-state READ_STATE_BODY) { // 計(jì)算已接收但未處理的消息體數(shù)據(jù)長(zhǎng)度 uint32_t body_data_in_buf conn-read_idx - conn-parsed_idx; // 計(jì)算還需要多少數(shù)據(jù)才能組成完整消息體 uint32_t body_remain conn-expected_body_len - conn-recvd_body_len; // 如果緩沖區(qū)里的數(shù)據(jù)已經(jīng)夠完成這個(gè)包 if (body_data_in_buf body_remain) { // 1. 提取完整的消息體 char* full_body conn-read_buf conn-parsed_idx; // 2. 這里可以調(diào)用業(yè)務(wù)處理函數(shù)例如handle_packet(full_body, conn-expected_body_len); printf(“[Info] Got a full packet, body length: %u\n”, conn-expected_body_len); // 3. 更新索引和狀態(tài) conn-parsed_idx body_remain; conn-recvd_body_len 0; conn-expected_body_len 0; conn-state READ_STATE_HEADER; packet_count; // 成功處理一個(gè)包 } else { // 緩沖區(qū)里的數(shù)據(jù)還不夠完成當(dāng)前消息體 conn-recvd_body_len body_data_in_buf; conn-parsed_idx conn-read_idx; // 所有數(shù)據(jù)都已用于當(dāng)前消息體 break; // 跳出循環(huán)等待更多數(shù)據(jù) } } } return packet_count; } // 主處理函數(shù) int conn_handle_read(Connection* conn) { int ret read_socket(conn); if (ret 0) { return ret; // 讀取失敗或連接關(guān)閉 } return parse_buffer(conn); // 嘗試解析緩沖區(qū) }這個(gè)狀態(tài)機(jī)邏輯是解決TCP粘包問(wèn)題的核心。它保證了無(wú)論底層數(shù)據(jù)如何到達(dá)我們都能正確地拼接出完整的應(yīng)用層消息包。4.3 緩沖區(qū)整理與性能優(yōu)化注意上面的parse_buffer函數(shù)在解析過(guò)程中parsed_idx和read_idx會(huì)不斷前進(jìn)。當(dāng)它們之間的數(shù)據(jù)被處理完后緩沖區(qū)前部會(huì)留下一段“已讀空洞”。為了高效利用緩沖區(qū)我們需要在適當(dāng)?shù)臅r(shí)候比如一次解析循環(huán)結(jié)束后將未處理的數(shù)據(jù)移動(dòng)到緩沖區(qū)頭部。// 在 conn_handle_read 的 parse_buffer 調(diào)用后可以添加緩沖區(qū)整理邏輯 void compact_buffer(Connection* conn) { if (conn-parsed_idx 0) { size_t remaining conn-read_idx - conn-parsed_idx; if (remaining 0) { memmove(conn-read_buf, conn-read_buf conn-parsed_idx, remaining); } conn-read_idx remaining; conn-parsed_idx 0; } } // 然后在 conn_handle_read 中在 parse_buffer 返回后調(diào)用 compact_buffer(conn);memmove的調(diào)用會(huì)有一定開(kāi)銷因此不必每次解析后都調(diào)用。可以設(shè)定一個(gè)閾值例如當(dāng)parsed_idx超過(guò)緩沖區(qū)大小的一半時(shí)再進(jìn)行整理這是一種空間換時(shí)間的權(quán)衡。5. 進(jìn)階議題與工程實(shí)踐實(shí)現(xiàn)了基本的狀態(tài)機(jī)解析一個(gè)生產(chǎn)級(jí)的網(wǎng)絡(luò)程序還需要考慮更多問(wèn)題。5.1 協(xié)議擴(kuò)展與靈活性基本的“長(zhǎng)度內(nèi)容”協(xié)議可能不夠用。我們經(jīng)常需要包含協(xié)議版本、消息類型、序列號(hào)等信息。一個(gè)更通用的協(xié)議頭可以這樣設(shè)計(jì)---------------------------------------------------------------------- | 版本(1B) | 類型(1B) | 序列號(hào)(2B)| 長(zhǎng)度(4B) | 消息體 (變長(zhǎng)) | ----------------------------------------------------------------------這樣狀態(tài)機(jī)在讀取固定長(zhǎng)度的頭部8字節(jié)后就能獲得更豐富的元信息再將剩余部分作為消息體處理。解析邏輯是類似的只是頭部結(jié)構(gòu)更復(fù)雜。5.2 超時(shí)、心跳與連接?;頣CP是面向連接的但連接可能因?yàn)榫W(wǎng)絡(luò)中斷、對(duì)端崩潰而變成“死連接”。應(yīng)用層需要心跳機(jī)制來(lái)檢測(cè)連接活性??梢栽趹?yīng)用層協(xié)議中定義一種PING/PONG類型的心跳包。服務(wù)器和客戶端定期如每30秒發(fā)送一個(gè)心跳請(qǐng)求對(duì)方收到后立即回復(fù)。如果連續(xù)多次未收到回復(fù)則判定連接失效并關(guān)閉。心跳包本身也是一個(gè)普通的應(yīng)用層數(shù)據(jù)包遵循同樣的“長(zhǎng)度前綴”協(xié)議。這保證了心跳邏輯和業(yè)務(wù)邏輯可以使用同一套編解碼框架。5.3 多線程與并發(fā)處理在高并發(fā)服務(wù)器中一個(gè)常見(jiàn)的模式是主線程I/O線程負(fù)責(zé)使用epoll等I/O多路復(fù)用技術(shù)接收數(shù)據(jù)完成TCP流到完整應(yīng)用層數(shù)據(jù)包的解析即我們上面實(shí)現(xiàn)的狀態(tài)機(jī)。工作線程池主線程將解析出的完整數(shù)據(jù)包連同對(duì)應(yīng)的連接信息放入一個(gè)任務(wù)隊(duì)列。工作線程從隊(duì)列中取出任務(wù)進(jìn)行業(yè)務(wù)邏輯處理如數(shù)據(jù)庫(kù)查詢、計(jì)算等然后將結(jié)果封裝成響應(yīng)包通過(guò)連接對(duì)象發(fā)回。這里的關(guān)鍵是連接對(duì)象Connection的線程安全。通常做法是一個(gè)連接在其生命周期內(nèi)只由一個(gè)I/O線程負(fù)責(zé)讀寫(xiě)避免復(fù)雜的鎖競(jìng)爭(zhēng)。工作線程處理完后通過(guò)線程間通信如管道、eventfd通知I/O線程有數(shù)據(jù)要發(fā)送或者直接將響應(yīng)數(shù)據(jù)放入一個(gè)屬于該連接的、帶鎖的輸出緩沖區(qū)由I/O線程在可寫(xiě)事件觸發(fā)時(shí)發(fā)送。5.4 流量控制與背壓即使解決了粘包如果發(fā)送方生產(chǎn)數(shù)據(jù)的速度遠(yuǎn)快于接收方處理的速度接收方的緩沖區(qū)會(huì)被填滿最終導(dǎo)致內(nèi)存耗盡。這需要通過(guò)應(yīng)用層流量控制來(lái)解決。一種簡(jiǎn)單的方法是使用窗口機(jī)制。接收方在協(xié)議中告知發(fā)送方自己還能接收多少字節(jié)的數(shù)據(jù)接收窗口。發(fā)送方發(fā)送的數(shù)據(jù)總量不能超過(guò)這個(gè)窗口。當(dāng)接收方處理完一部分?jǐn)?shù)據(jù)后再更新并通告新的窗口大小。這模仿了TCP本身的滑動(dòng)窗口但在應(yīng)用層給了我們更靈活的控制能力可以基于業(yè)務(wù)處理能力而非網(wǎng)絡(luò)帶寬來(lái)進(jìn)行流控。6. 常見(jiàn)問(wèn)題與調(diào)試技巧在實(shí)際編碼和調(diào)試中你肯定會(huì)遇到各種詭異的問(wèn)題。這里記錄幾個(gè)典型的坑和排查思路。6.1 問(wèn)題排查清單現(xiàn)象可能原因排查步驟接收方解析出錯(cuò)誤的消息長(zhǎng)度巨大值字節(jié)序未轉(zhuǎn)換。發(fā)送方未用htonl或接收方未用ntohl。1. 抓包tcpdump/wireshark直接查看線上傳輸?shù)?字節(jié)長(zhǎng)度字段的值。2. 對(duì)比發(fā)送端內(nèi)存中的值主機(jī)序和網(wǎng)絡(luò)包中的值應(yīng)為網(wǎng)絡(luò)序。接收方一直卡在READ_STATE_HEADER狀態(tài)數(shù)據(jù)未到達(dá)或接收不完全??赡苁蔷W(wǎng)絡(luò)延遲、丟包或接收緩沖區(qū)設(shè)置太小。1. 打印read_idx和parsed_idx看是否持續(xù)有數(shù)據(jù)讀入。2. 檢查read系統(tǒng)調(diào)用的返回值確認(rèn)是否被信號(hào)中斷EINTR。3. 使用netstat -t查看該連接的Recv-Q是否堆積。接收方解析出的消息內(nèi)容亂碼或截?cái)唷皩?xiě)一半”問(wèn)題。發(fā)送方分多次send中間被操作系統(tǒng)調(diào)度打斷。1. 確保發(fā)送方使用“緩沖區(qū)拼接一次發(fā)送”或writev。2. 抓包查看一個(gè)邏輯數(shù)據(jù)包是否被拆成了多個(gè)TCP段發(fā)送這可能是正常的但接收方是否按長(zhǎng)度正確重組。服務(wù)端內(nèi)存緩慢增長(zhǎng)直至OOM緩沖區(qū)未整理。memmove邏輯有誤或從未執(zhí)行導(dǎo)致緩沖區(qū)頭部空間無(wú)法復(fù)用。1. 在compact_buffer函數(shù)前后打印緩沖區(qū)指針和索引。2. 檢查parsed_idx增長(zhǎng)邏輯確保一個(gè)包處理完后parsed_idx正確前移。連接隨機(jī)斷開(kāi)且伴隨大包傳輸未設(shè)置SO_SNDBUF/SO_RCVBUF。默認(rèn)緩沖區(qū)可能不夠?qū)е伦枞騺G包。1. 使用setsockopt適當(dāng)調(diào)大發(fā)送和接收緩沖區(qū)大小。2. 對(duì)于海量數(shù)據(jù)傳輸考慮在應(yīng)用層實(shí)現(xiàn)分片/重組機(jī)制。6.2 調(diào)試?yán)骶W(wǎng)絡(luò)抓包與日志W(wǎng)ireshark/tcpdump這是網(wǎng)絡(luò)程序員的“顯微鏡”。當(dāng)協(xié)議解析出現(xiàn)問(wèn)題時(shí)第一反應(yīng)就應(yīng)該是抓包。你可以清晰地看到每一個(gè)TCP報(bào)文段以及里面攜帶的原始字節(jié)。對(duì)照你的代碼檢查長(zhǎng)度前綴字段的4個(gè)字節(jié)到底是什么例如00 00 00 0A表示長(zhǎng)度10一個(gè)完整的應(yīng)用層消息是否被拆成了多個(gè)PSH包是否有預(yù)期之外的重傳或亂序結(jié)構(gòu)化日志在你的狀態(tài)機(jī)關(guān)鍵節(jié)點(diǎn)添加日志。但要注意性能使用條件編譯或日志級(jí)別控制。// 在調(diào)試階段可以這樣 #define DEBUG 1 #if DEBUG #define LOG(fmt, ...) fprintf(stderr, “[%s:%d] ” fmt “\n”, __FILE__, __LINE__, ##__VA_ARGS__) #else #define LOG(fmt, ...) ((void)0) #endif // 在狀態(tài)機(jī)中 LOG(“State: %d, read_idx: %u, parsed_idx: %u, expected_len: %u”, conn-state, conn-read_idx, conn-parsed_idx, conn-expected_body_len);6.3 邊界條件與防御性編程網(wǎng)絡(luò)環(huán)境惡劣必須對(duì)任何來(lái)自網(wǎng)絡(luò)的數(shù)據(jù)持不信任態(tài)度。長(zhǎng)度字段校驗(yàn)解析出長(zhǎng)度后必須檢查其合理性。是否超過(guò)最大允許值如MAX_PACKET_SIZE是否為0如果協(xié)議不允許空消息體內(nèi)存分配檢查如果根據(jù)長(zhǎng)度字段分配內(nèi)存一定要檢查分配是否成功。循環(huán)退出條件解析循環(huán)while (conn-parsed_idx conn-read_idx)必須確保在解析完一個(gè)完整包后索引被正確更新否則會(huì)導(dǎo)致死循環(huán)。連接狀態(tài)管理在read返回0對(duì)端關(guān)閉或負(fù)數(shù)錯(cuò)誤時(shí)必須及時(shí)關(guān)閉套接字并清理對(duì)應(yīng)的Connection資源防止內(nèi)存泄漏。7. 從零構(gòu)建一個(gè)簡(jiǎn)單的Echo服務(wù)器示例最后我們整合所有知識(shí)實(shí)現(xiàn)一個(gè)簡(jiǎn)單的、使用長(zhǎng)度前綴法的Echo服務(wù)器。它接收客戶端發(fā)來(lái)的任何數(shù)據(jù)包并在前面加上“Echo: ”前綴后發(fā)回。服務(wù)器端核心代碼框架// server.c (部分代碼) #include “connection.h” #include sys/socket.h #include netinet/in.h #include unistd.h #include stdio.h #include stdlib.h #include string.h #define PORT 8080 #define MAX_EVENTS 10 void handle_full_packet(Connection* conn, const char* body, uint32_t len) { // 構(gòu)造響應(yīng) “Echo: ” 原始消息體 char response[1024]; const char* prefix “Echo: “; size_t prefix_len strlen(prefix); // 防御性編程檢查響應(yīng)是否超長(zhǎng) if (prefix_len len sizeof(response)) { const char* err_msg “Message too long”; send_packet(conn-fd, err_msg, strlen(err_msg)); return; } memcpy(response, prefix, prefix_len); memcpy(response prefix_len, body, len); // 使用我們封裝好的函數(shù)發(fā)送響應(yīng)包 send_packet(conn-fd, response, prefix_len len); } int main() { int listen_fd socket(AF_INET, SOCK_STREAM, 0); // ... 設(shè)置SO_REUSEADDR, bind, listen 等標(biāo)準(zhǔn)步驟 ... // 簡(jiǎn)化起見(jiàn)這里用select實(shí)際項(xiàng)目建議用epoll fd_set read_fds; Connection* conn_array[FD_SETSIZE] {NULL}; while (1) { FD_ZERO(read_fds); FD_SET(listen_fd, read_fds); int max_fd listen_fd; // 將已連接的socket加入監(jiān)聽(tīng)集合 for (int i 0; i FD_SETSIZE; i) { if (conn_array[i] conn_array[i]-fd 0) { FD_SET(conn_array[i]-fd, read_fds); if (conn_array[i]-fd max_fd) max_fd conn_array[i]-fd; } } int activity select(max_fd 1, read_fds, NULL, NULL, NULL); if (FD_ISSET(listen_fd, read_fds)) { // 接受新連接 int new_fd accept(listen_fd, NULL, NULL); // 為新連接創(chuàng)建Connection對(duì)象并初始化 for (int i 0; i FD_SETSIZE; i) { if (!conn_array[i]) { conn_array[i] (Connection*)malloc(sizeof(Connection)); conn_init(conn_array[i], new_fd); break; } } } // 處理已連接套接字的可讀事件 for (int i 0; i FD_SETSIZE; i) { Connection* conn conn_array[i]; if (conn FD_ISSET(conn-fd, read_fds)) { int ret conn_handle_read(conn); if (ret 0) { // 連接錯(cuò)誤或關(guān)閉 close(conn-fd); free(conn); conn_array[i] NULL; } else if (ret 0) { // ret 代表處理了多少個(gè)完整包這里簡(jiǎn)化處理 // 在實(shí)際的conn_handle_read中每解析出一個(gè)完整包應(yīng)回調(diào)handle_full_packet // 為了示例清晰我們將回調(diào)機(jī)制省略實(shí)際應(yīng)在parse_buffer內(nèi)部調(diào)用回調(diào)函數(shù) printf(“Processed %d packets from fd %d\n”, ret, conn-fd); } // 整理緩沖區(qū) compact_buffer(conn); } } } return 0; }這個(gè)示例省略了錯(cuò)誤處理、信號(hào)處理、線程池等細(xì)節(jié)但它清晰地展示了如何將我們之前討論的Connection狀態(tài)機(jī)整合到一個(gè)事件驅(qū)動(dòng)模型中。在實(shí)際項(xiàng)目中conn_handle_read內(nèi)部解析出一個(gè)完整包時(shí)應(yīng)該通過(guò)函數(shù)指針或C虛函數(shù)等方式回調(diào)業(yè)務(wù)邏輯處理函數(shù)如示例中的handle_full_packet。最后一點(diǎn)體會(huì)TCP粘包/拆包問(wèn)題就像網(wǎng)絡(luò)編程的“第一課”它強(qiáng)迫你從字節(jié)流的視角去理解網(wǎng)絡(luò)通信。長(zhǎng)度前綴法是你工具箱里最可靠的那把扳手。理解并實(shí)現(xiàn)好這個(gè)基礎(chǔ)框架后你才能在此基礎(chǔ)上構(gòu)建更復(fù)雜的協(xié)議、路由、集群和分布式系統(tǒng)。所有的復(fù)雜都源于對(duì)簡(jiǎn)單的精準(zhǔn)掌控。
返回列表
PREV
查看更多資訊
NEXT
返回資訊列表
六月婷婷青青青视频| 欧美色色色| 久久久久亚洲AV无码网影音先锋| 日本在线视频播放91| 久久影视婷婷五月| 思思99热| 亚洲成人AV在线观看| 亚洲AVwwwwwww| 深爱激情综合| 蜜乳.comcom| 亚洲第一成人无码A片| 五月天婷婷影院影院| 日本三级毛片| 久久人人添人人爽添人人片αV| 99无吗| 婷婷五月天丁香成人社区| 婷婷97碰碰| 夜夜噜夜夜奇| 丁香色六月| 大香蕉福利导航| 香蕉婷婷色五月| 99热99在线| 人妻精品久久久久久| 97资源碰碰| 五月综合色| 丁香五月婷婷六月| 99视频在线观看视频| AV动漫不卡无码免费| 久青草影院| 米奇影视资源婷婷狠狠色激情欧美五月丁香 | 影音先锋一区二区三区| 亚洲九九视频| 日日夜夜久| 欧美天天五月丁香免费观看| 婷婷99狠狠| 五月天婷婷丁香视频| 艹天天射| 狼人狠狠操| 97在线视频 欧美| 久久婷婷视频| 色婷婷视频| 婷婷五月成年人| 狠狠爱青青草| 亚洲精品一区无码A片| 丁香婷婷啪啪啪| 色婷婷888| 三日本无码| 人人播| 五月花丁香婷婷| 久久久婷| 五月开心婷婷网| 色色色色色色色色色色色色色色,网站| 亚洲六月色婷婷| 久草xx性爱视频| 婷婷开心深爱五月天| 91亚洲视频| 成人精品一区日本无码网| 免费无码毛片一区二区A片 | 久99热| 色婷婷综合网站| 91人妻色色网| 精品久色| 亚洲天天免费| 开心四月婷婷在线色播播| 丁香 久久| 九九re视频在线视频| www.色多多婷| 欧美精品狠狠色丁香婷婷| 天天插天天日| 精品国产乱码久久久久久免费| 色色色色色色色色色色色色色97| 色综合色五月| 婷婷五月花| 97干在线视频| 人妻熟人中文字幕一区二区| www久| 综合色影院| 婷婷成人五月天成人文学| 久久机热这里只有精品| 色亭亭丁香五月天| 人人操人| 超碰无码318604| 五月丁香婷婷综合网色欲| 97碰碰免费.视频| 夂夂夂夂夂夂夂夂夂夂夂夂夂夂夂夂夂夂夂亚洲亚洲亚洲亚洲亚洲亚洲亚洲亚洲色 | 思思久久96热在精品国产,| 久久亚洲天堂| 99er这里只有精品| 五月天性色| 中文久久久人妻| 色五月激情问网站| www.狠狠干com| 日韩精品二三区| 五月天堂六月丁香亚州中文字幕久久| 精品国婬伦V无码久久久| 久操婷婷| 丁香啪啪中文字幕| 超碰99热| 日韩操| 五月天激情婷婷五月天久久| 五月丁香性| 色亚洲激情| site:pnnrt.com| 五月天婷婷丁香导航| 亚洲激情五月婷婷日日| 在热视频精品| 26uuu国产| 欧美在线视频99| 图片区 小说区 区 亚洲五月 | 九九99香蕉在线视频播放| 第四色五月天| 欧美日韩99| 最新色色五月天| 99热在线播放| 中文字幕综合| 五月婷婷啪啪网| 五月丁香六月婷婷中文版| 亚洲一区二区无码蜜乳av| 亚洲日日日| PORNY九色9l自拍视频成人| 99性视频| 久久狠狠干| 五月天亚洲最大成人| 99性感视频| 激情六月婷婷| 日韩青青| 五月天婷婷激情网| 色激情五月| 综合五月天| 第四色大香蕉| 丁香五月婷婷色| 碰97久久| 91oumei| 97色色视频| 97一区二区| 97人人看一| 久色成人| 99久久久久| 五月开心啪啪| 婷婷五月天成人小说| 4399成人黄A片| 刘玥精品一区| www.六月丁香看AV| 八戒青柠影视剧在线观看| 日本久热| 大香蕉婷婷五月| 久综合4| 久久久久9999| 婷婷婷婷色| 99热 在线播放| 超碰精品手机在线| 99草视频在线观看| 久久婷婷五月综合啪| 色情丁香五月婷婷精品| av激情在线| 激情五月丁香婷婷夜夜操| 婷婷五月天香蕉| 综合久久婷婷| 婷婷五月天av网| 殴美日韩成人| Www99热| 婷婷五点亚洲| aaa9区免费在线观看| 婷婷丁香成人在线视频| 婷婷五月天小说| 亚州精品色情无码A片| 色婷婷五月天| 97资源欧美日韩大香蕉超碰一区| 色五月五月婷婷| 婷婷激情四射五月天| 五月天激情中文字幕| 任你艹| 丁香婷婷五月激情| 无码啪啪| 激情婷婷内射| 操B视频在线播放| 99热日韩这里只有精品| 色色五月天婷婷丁香| 免费成人中文字幕| 五月丁香六月色| 99re视频在线| 婷婷欧美综合| 色色综合色视频| 色99视频| 一本道综合网| 五月婷婷69| 琪琪色网在线| 日本色五月婷婷| 91日综合欧美| 亚洲久热| 欧美噜一噜| 色综合视频在线| 99综合免费视频| 操老逼综合网| 久色五月丁香视频| 性五月激情| 五月婷婷激情久久| 婷婷五月色丁香在线看| 日本3级片一区2区| 超碰人人在线| 六月丁香综合| 狠狠色五月激情| 在线看的免费网站| 色香久久| 激情婷婷五月天在线观看| 亚洲午夜在线视频| 啪啪操超碰| 狠狠色97| 26uuu国产色| 色婷婷在线视频| 激情狠狠丁香月| 激情五月九九九| 碰碰女| 狠狠色婷婷7| 亚洲亚洲人成综合网络| 色色色在线观看| 夜夜夜天天操| 丁香五月天天| 99热网站| 丁香五月天堂网| 99成人网一区| 色色日本欧美| 精品人妻在线免费观看| 色~性~乱~伦~噜| www.久久| 久久色五月天| 99热日韩| 六月婷婷无码观看| 7超碰自拍| 色婷视频| 五月丁香啪啪综合| 婷婷五月天啪啪| 亚洲色图五月丁香| 九久九精品| 五月丁香无码| 在线1青婷| 综合五月婷婷| 色五月偷偷| 精国产品一区二区三区A片| 五月婷婷基地| 深爱五月天婷综合| 九九热这里只有精品首页| 操婷婷基地| .操區COm| WWW.婷婷五月天.COM| 99热精品在线观看| 99热婷婷| 九九综合色综合| 久久性爱视频久久性爱视频| 欧美毛片www| 成人av在线电影| 久9精品视频在线| 5月丁香啪啪啪| 九九免费精品| 婷婷色5月激情网| 五月丁香六月婷婷中文版| 182TV亚洲| 大香蕉福利导航| 这里只有精彩视频| 色色性爱视频| 婷婷五月色情| 五月天丁香综合久久国产| 丁香六月婷婷缴情欧美| 亚洲乱码日产精品BD| 色天堂在线| www.色五月.com| 人妻久久久久久久久妻久久久久| 久久与婷婷| 婷婷色网| 侠女刀之记忆电影在线看免费| 7777精品伊人久久久大香线蕉最新版| 丁香五月www| 99色在线观看视频者| 色婷婷丁香五月| 五月丁香啪啪啪| 美女网黄| 激情婷婷五月天| 日韩久久视频| 色五月综合网| 97在线观视频免费观看| 亚洲在线操| 狠狠干,狠狠操| 97色色在线视频| 日韩成人精品一区久久久久| 五月天激情中文字幕| 夜夜骑夜夜操| 婷婷丁香六月| 久久六月婷婷| 中文字幕精品推荐免费在线观| 激情综合啪啪| 曰韩少妇内射免费播放| ztEJj| 日本波多野结衣视频| www.seqingwuyuetian| 婷婷五月天成人| 五月丁香| ww超碰在线| 久久影视婷婷五月| 91色在线/日韩| 综合色久| 天天精品视频在线观看视频| 狠狠爱五月婷婷| 五月丁香激情综合啪啪| 性综合网| 色色热| 国产精品91抖高| 亚洲欧美日韩另类| 久久XX| 免费99情趣网视频| 99在热线免费视频| 久操大香蕉| 色人久久| 六月婷婷视频| 人人人人人人人人人草| 婷婷五月六月激情| 丁香六月婷婷综情欧美| 超碰在线精品| 最新精品视频99| 久久人妻高清中文| 五月天激情电影| 中文字幕人成乱码在线观看| 91传媒无码人妻精| 色八月婷婷| 极品 少妇 内射| 日婷婷久久开心| 婷婷丁香在线| 51精品国内探花| 日夜操B| 亚洲婷婷丁香五月亚洲| 亚洲午夜视频| 丁香六月婷婷激情| 婷婷五月蜜桃成人桃色丁香| 丁香五月婷婷五月天| 激情综合激情五月| 四虎成人精品永久免费AV九九| 激情99| 激情小说在线视频| 色综合久久88色综合天天看| va亚洲中文在线| 第四色五月婷婷| 婷婷五月天福利| 男人的天堂97| 色婷婷五月天在线| www久久久| 特级操b片| 五月天婷婷丁香花| 99激情视频| 国产真人做爰视频免费| 国产成人网站在线观看| 欧美日本va| 久久久中文| 99视频在线观看视频| 色婷丁香五月| 久久Xx| 97色五月婷婷在线| 婷婷五月天天| AA片在线观看视频在线播放| 五月大香蕉| www,天天干| 国产美女无遮挡裸体毛片A片| 九九大香视频| 激情五月激情综合网| 琪琪布丁香社区激情五月天| 五月天激情在线视频| 亚洲熟妇无码乱子AV电影| 久热在线中文字幕色999舞| 精品人人操| 可以免费观看的av| 色99在线看| 97香蕉人人在线观看| 亚洲婷婷丁香五月亚洲| 亚洲人妻av| 欧洲亚洲免费视频9| 色色网五月激情| 欧美婷婷综合| 熟女国产在线一区二区三区四区| 天天爽日日爽夜夜爽| 影音先锋男人站,影音先锋男人色资源网,影音先锋AV最新资源站,影音先锋AV资源 | 丁香五月婷婷五月| 亚洲sesesese| 九九av| …亚洲黄色在线播放日韩、av中文a…| 深爱开心五月天| 婷婷九月色| 碰碰碰91| 五月婷婷啪啪网| 婷婷五月天综合AV| 欧洲亚洲免费视频9 | 99爱免费视频| 五月婷色丁香| 亚洲激情久久| 丁香九色不卡aaa| 婷婷精品综合| 婷婷色吧| 欧美在线视频99| 婷婷丁香九月| 天天舔天天爽| 久久五月天激情视频| 无码99| xxxx五月激情| 激情五月婷| 色综合色综合婷婷热| 精品夜夜澡人妻无码AV| 亚洲婷婷久久综合| 久久婷婷五月综合色奶水99啪| 五月天婷婷色综合| 大香蕉五月天婷婷丁香91| 激情四射五月天| 青青草蜜臀| 九月婷婷激情久久| 99热这里是精品| 六月天六月婷| 婷婷丁香六月| 碰人人97| 开心五月色婷婷综合开心网| 国产精品电影网| 99人这里只有精品| 97超碰在线免费观看| 人妻少妇色综合| 深爱五月最新网址| 精品无码av丁香五月激情| 9色操| 国产午夜一区二区三区| 99免费热视频在线| 天天干天天操天天干天天操天天干天天操| 成人婷婷| 天天综合91入口| A久久| 成人视频在线免费播放| 婷婷五月天a| 婷婷久久五月| 婷婷玖玖五月天| 99re欧美精品| 俺去也婷婷| 久久精品五月天| 青草激情在线| 九九久久99| 色五月天电影| 婷婷免费无视频| 婷婷放心五日爱| 少妇婷婷五月天| 久久精品熟女亚洲AV麻豆| 丁香五月Av| 丁香五月天啪啪| 五月婷六月丁香| 狠狠色婷婷7| 97影院一级片| 9色在线视频| 伊人久久中文网| 九月激情婷婷丁香| 成人αV视频免费观看| 99视频只有精品| 久久久久久97| 色九月婷婷综合| 国产成人亚洲综合A∨婷婷| 九九爱看亚洲| 久久综合天天综合| 停停五月天激情网| 成人综合伍月天| 久色五月婷婷综合| 久久激情五月天| 色婷婷五月天在线| 六月婷婷激情小说网| 欧美毛片www| 5月婷婷6月丁香aV| 午夜精品777| 天天成人综合| 99热只有精品在线观看| 亚洲色激情| 免费观看欧美成人AA片爱我多深| 婷婷丁香五月亚洲| 激情久久丁香| 婷婷九月色| 超碰在线91| 五月婷婷中文| 国产精产国品一二三在观看| 91九九九色在| 婷婷色色欧美| 久热9| 这里只有精品偷拍| 夜夜夜夜操| 人人看人人要| 久草大| 亚洲色色香蕉| 五月丁香操婷逼| 99亚洲天堂| 五月天婷婷小说| 久久小说| 99色.com| 欧美丁香婷婷天天操| 久久这里面只有精品视频| 婷婷黄色五月天在线视频| 日韩AV色色色| 日韩超碰在线| 99热这里有精品| 九九XX视频| 婷婷五月天AV在| 91日本在线观看| 六月丁香啪| 欧美97p| 激情图片婷婷丁香五月| 婷婷成人五月天| 九月婷婷综合色干| 午夜一区| 色婷婷视频综合| 婷婷五月天亚洲五码| 婷婷伊人网| 丁香五月五月婷婷欧美大香蕉 | 99热这里只有精品22| 五月天激情AV| 婷婷五月天电影网| 97操在线资源| 狠狠另类视频| 99久久99久久| 久久人人添人人爽添人人片αV| 五月丁香久久综合色| 久久99热这里只有精品首| 亚州精品久久久久AV无码| 97性视频| 亚洲不卡123| 亚洲综合激情五月久久| 五月丁香激情婷婷| 亚洲成av人影院| www.一起草av| 青青草婷婷综合五月| 99超级碰碰| 精品久久久久成人码免费动漫| 中文在线成人| 成人.在线日韩| 久久婷婷五月综合啪| 日本色婷婷久久99精品91| 五月亭亭直播| 成人在线观看国产| jiqingtaose五月天| 综合五月网| 99操碰| 六月婷婷七月丁香| 色婷婷五月天不卡| 国产精品第一国产精品| 无码se| 国产成人亚洲综合A∨婷婷| 日日干夜夜干| 色亚洲无码| 99精品综合| www.wuyuetian啪啪| 99视频超级精品| 欧美大香蕉视频| 超碰成人影视| 婷婷激情丁香六月| 婷婷五月丁香高清无码| 亚洲欧洲另类| 国产在线黄色| 91操片| 久热久操久热久草国产91| 日韩成人精品一区久久久久| 超碰av在线| 六月色婷婷色| 日韩1区2区| 超碰三级片| 激情五月天社区| 99久久久精品| 天天色综网| 99久久超级| 婷激情五月| 狠狠五月婷婷| 婷婷激情五月综合丁| 国产高潮A片羞羞视频涩涩| 99这里只有精品视频免费| 久久久WWW| 大香蕉伊人99| 日本高清久久| 深爱五月婷婷开心中文字幕| 99精品成人无码A片观看金桔| 婷婷综合另类小说| 高清无码网址| 丁香久久五月天视频在线观看| 国产日比| 婷婷日日天天| 一级性爱大片| enecarbon-materials.comWu染请涟系Bao护@wip1688 | 九九热这里只有精品7| 在线视频你懂得| www.色婷婷| 日日干夜夜干| 日本九九热| 婷久久久| 久久久27操| 亚洲精品成人| 国产欧美日韩综合精品一区二区| 色五月婷婷丁香婷婷| 猫咪伊人AV| 九热视频| 九九热a| 国产精品18久久久| 亚洲99热| 久热九九| 成人在线观看精品| 激情综合五月婷婷| 开心婷婷五月天综合| 色五月丁香六月资源站| 香蕉AV福利精品导航| 五月丁香六月花| 2021日韩无码| 色色色色热| 一本道综合网| www,超碰| 国产成人精品亚洲线观看| 五月天俺去也| 色婷婷视频| http://www.com久久久精品一区| 亚洲热视频| av九九| 秋霞AV吧| 任你草| 国色天香伊人狠狠色| 六月婷婷啪啪| 久久国产一区二区三区| 色色99| 视频免费精品免费精品免费精品免费精品免费精品免费精品免费99 | 久久九九爽| 丁香五月综合在线播放| 久久丁香五月| yjzz亚洲国产| 亚洲色另类| 五月婷婷激情综合视频| 去干网av| www,com,五月色色| 色五月综合激情网| 色综合久久综合中文综合网| 六月丁香五月激情婷婷| 午夜大香蕉| 色综合77777| se99视频| 丁XX 成人| m色激情网| 99久久99视频只有精品| 伊人五月天97| 9色小视频在线观看| 五月天激情网图片| 丁香 久久| 婷婷丁香色五月久久88| 丁香五月丐人妻| 中文字幕综合| www.五月丁香av| 综合色情网| 丁香花五月天社区| 91色性感五月婷婷丁香| 免费AV播放| 99啪| 91激情五月开心| 丁香五月六月婷婷殴美综合| 亚洲 小说 欧美 激情 另类| 欧洲永久精品| 99 热国产在| 国产av影片| 天天网曰日曰夜夜综合永久免费| 婷婷中合| 日韩av一区二区在线/日产精品久久久 | 性欧美大战久久久久久久83| 色狠狠综合| 色婷婷久久| 亚洲成人av在线| AA丁香综合激情| 色欲色香伊人| 噜噜色婷婷| 亚洲aV写真天天综合网久久| 亚洲狠狠操| 亚洲综合婷婷| 天堂婷婷丁香六月网| 婷婷五月天少妇| 色综合婷婷| 五月丁香黄色视频| 久久婷婷伊人| 玖玖资源在线视频| 五月开心久久| 婷婷色中文字幕| 天天插天天日| 天天操天天插| 国产精品久久久久久喷浆| 色偷偷AV亚洲男人的天堂| 这里只有精品视频| 精品影院| 91久久国产自产拍夜夜91久久精品文字>91麻豆精品国产 | 在线观看日韩12345区| 伊人丁香五月天丁香在线婷| 色就色94欧美setu| 超碰京东热av男人的天堂| 91在线观看www| 免费成人中文字幕| 成年人夜夜喷水| 色~性~乱~伦~噜| 久久亚洲A| 开心五月婷婷六月丁香| 99热色在线精品| 这里有精品2| 天天爱天天爽| 金品在线视频99| 97在线精品视频| 亚洲色色色色色色色色色| 青青热久久综合| 欧美熟女乱又伦| 天天激情| 亚洲综合婷婷| 国产3p露脸普通话对白| 禁片二区| 精品成人久久久久久久_一二三四视| 欧美久热| 国际国外精品欧洲南美洲专区无码不卡| 丁香久久久| 色婷久| 丁香五月激情五月| 色吧99| 久久色天堂| 欧美天天干五月丁香| 这里只有精品免费视频在线观看| 五月天社区婷婷丁香社区| 天天艹夜夜艹| 精品操逼一区二区| 激情五月天久久丁香| 五月激情基地| 五月婷婷三级| 五月天婷婷婷| 欧美久久婷婷| 五月丁香色婷婷熟女| 九九综合色综合| 激情第四色| 伊人影院久久网| 丁香婷最新动态| 99热无码首页| 丁香六月天| 日韩黄色电影| 开心五月婷婷激情网| 丁香五月六月婷婷综合| 五月天婷婷久色| 婷色五月天| 丰满少妇猛烈A片免费看观看 | 婷婷综合97| 色婷婷五月天综合网| 久久资源网五月婷| www.亚洲激情.com| 色之综合网| 天天日夜夜爽| 性生生活大片又黄又| 99在线公开视频| 色狠狠综合| 色色色欧美| 色欲五月婷婷| 日韩无码色色| 99热10在线高清播放| 五月婷婷激情综合在线| 五月婷婷亚洲| 久久婷婷六月综合综合| 五月丁香久久激情网| 欧美25p| 大香蕉伊人99| 六月丁香激情| 狠狠色丁香久久综合婷婷亚洲成人福利| 五月丁香婷成人网| 99热国产这里只有精品| 九九大香视频| 久久婷婷五月天蜜桃| 香蕉网婷婷| 丁香五月婷婷成人综合| 欧美色频| 99精品国产在热久久| 26UUU欧美激情一区二区| 欧美超碰亚洲| 夜夜操,天天撸| 九九色婷| 99er6热在线观看精品6| 九九热123| 六月丁香综合999| 色五月综合| 综合五月丁香久久| 色婷婷久久| 综合亚洲六月婷婷在线| 五月婷婷天| AV中文在线| 久久99网| 五月花综合网| 精品无码久久久久久久久| 天天肏屄夜夜爽| 婷婷在线视频| 色五月婷婷五月久久| 国产精品一区在线观看你懂的| 国产伦理精品高清在线观看网站一区二区 | 99热在线里有精品| 国产JK精品白丝AV在线观看| 丁香五月成人论坛| 免费看欧美成人A片无码| 天天插天天很| 色五月色综合| 亚洲黄网在线| 五月丁香六月婷婷在线| 色九月国产| 丁香五月天黄色片| 五月丁香六月婷婷亚洲天堂网站| 人人摸人人干| 成人婷婷五月| 色yeye色综合| 欧美视频五区| 国产精品久久久99视频| 国产精产国品一二三在观看| 五月激情婷婷播播网| 黄色av网站在线免费播放| 噜噜久| 五月婷中文娱乐综合| 五月婷婷六月情| 91久久久久久久久18| 久久综合九九| 激情色视频| 五月丁香激| 超碰91在线| 日撸夜撸日操| 99re热在线观看| 九九无码| 天天撸天天干天天插| 丁香五月婷婷偷拍| 婷婷亚洲天堂| 久久思思精品| 久久人人看| 青青草青青草五月天| 丁香六月婷| 欧美欧盟性爱网| 91狼友视频在线观看| 婷婷少妇激情| 丁香花五月天| 婷婷丁香亚洲色综合91| 亚洲色五月| 99亚洲视频| 激情丁香久久| 97在线日本| 亚洲va综合va国产va中文| 亚洲久热无码| 九九色综合九九色| 亚洲VA在线| 亚洲视频五区| 亚洲AV成人精品网站在线播放| 久久色天堂| 亚洲精品久久久久久久久久吃药| 黄色一级影片| 色色欧美。| 超碰人人草| 亚洲色情网站| 色久在| www、丁香五月天| 99热在线观看| 婷婷丁香五月综合| 五月亚洲| 伊人成人宗合网| 97欧美在线| 91黄色五月天视频| 婷婷视频网| 天天搞天天色综合| 成人电影丁香六月天| 99热99在线| 亚洲碰碰碰| 九九久久9 9在线观看| 人妻久久久久久久 | 婷婷六月开心网| 色综合激情| 成人在线视频一区| 日逼影音先锋男人资源站| 久99| 激情小说五月天| 激情五月综合网| http://www.sd-xiangsu.com/| 婷婷色五月天第7色| 婷婷中文在线| 五月综合激情| 九九中文字幕九| 刘玥精品一区| 黄桃AV无码免费一区二区三区| 成人午夜无码视频| 五月婷婷九九热| 操逼电影免费看| 乱岳熟女50岁| 在线另类| 直接看的av| 亚洲不卡| 欧美99视频| 亚洲另类日本| 久久AAAA片一区二区| 久久人妻乱子伦| 五月婷婷视频啪啪美女| 狠狠色婷婷7777久| 亚洲综合色色| 久久99精品久久久久久噜噜| 婷综合| 狼人狠狠操| 久久Xx| 日本五月天激情| 日日日影院| 日逼免费视频 | 99'无码| 五月天婷婷激情网| 久久婷狠狠色| 大香蕉五月婷婷| 在线观看996精品| av第一二区| 五他月天啪啪啪| 无码字幕中文| 亚洲天堂制| 九月丁香很很色| 色五月激情五月| 无码激情AAAAA片-区区 | 天天影院色| 九九热99热| 无码色色色| 精品影院| 免费看片在线观看| ...婷婷五月综合不卡,国产在线手机| 最新无码专区| 超碰免费人人| 五月丁香六月色婷| site:hcxsz888.com| 99久久婷婷综合| 另类亚洲电影| 青青草婷婷久久| 婷婷五月天毛片| 亚洲情欲久久| 欧美色偷偷大香| 五月婷中文娱乐综合| 五月 婷 久| 射久久丁香五月| 婷婷五月天色色| 婷婷六月综合在线| 手机免费福利视频| 日韩精品一区二区亚洲AV观看 | 涩综合在线 | 婷婷.com| 丁香激情久久| 国产亚洲网站在线| 久草性爱| 九九re精品视频在线观看| 欧美成人Va| 天天操天天日天天操| 97碰人人操| 九九热九九| 嫩草哈哈操| 色婷婷欧美| 色婷婷五月天激情综合| 激情五月天在线免费美女视频| 色色操| 婷婷丁香18| 99超级碰碰| 激情五月综合ì香亚洲| 五月丁香婷婷深深爱| 婷婷五月天影院| Caoub青青超碰 | 久久成人性爱| 类似婷婷激情综合网站| 亚洲综合五月天婷婷丁香| 热久久婷婷| 综合亚洲六月婷婷在线| 婷婷五月天激情基地| 色色色无码| Caoub青青超碰| 婷婷久久欧美| 婷婷五月天狠狠色| 国产毛片精品一区二区色欲黄A片| 色五月自偷自拍婷婷婷婷| 激情六月丁香综合| 天天干天天操天天爽| 精品无码久久久久久久久| www狠狠com| 婷婷五月天com| 99热99在线| 色综合色综合色综合| 亚洲视频在线观看99| 九九视屏| av一区二区电影免费在线观看| 99 热| 色欲久久久久久综合网综合网| 免费观看18视频网站| 国产avapp 网| 啪啪六月婷婷| 午夜精品久久久久久久爽| 六月激情婷婷| 丁香五月中文字幕色播| 婷婷伊人欧美| 婷婷激情综合色五月久久,色婷婷丁香花,丁香婷婷五月情天,久久婷婷五月综合色 | 婷婷视频在线| 色婷婷六月性| 久久草大香蕉| 欧洲S级在线观看| 俺也去在线视频| 成人国产欧美大片一区| 国产1区2区3区在线观| 激情五月天开心| 九九99热精品| 五月色婷婷激情| www.夜夜操| 五月天啪啪| 99性视频| 天天噜日日噜综合无码| 人人摸人人澡人人| 天天肏天天肏| 丁香五月婷婷影院| 久久丁香网| 天天日夜夜爽。| 日韩AV无码影片| 日日操夜夜爽天天天| 99热在线观看| 久久久久久久综合狠狠综合| 综合激情站| www99热| 国产成人99久久亚洲综合精品| 色碰干| 中文无码婷婷| 超碰人人艹| 欧美日韩999| 精品成人久久久久久久_一二三四视| 丁香五月婷婷综合精品素人| 国产超碰人人| 日韩操逼大片| 久婷五月| 激情网五月天| 天天噜天天爱| 2018夜夜草| 色日本网| 欧洲综合一区| 激情五月六月婷婷| 操久久精| 国产亚洲99久久精品| ay2区| 色五月情| 婷婷五月天综合小说网| www一起操在线观看| 强伦轩人妻一区二区电影| 日韩欧美一级大黄网站| 91操碰| 婷婷涩五月天综合| 五月婷婷国产| 欧美日韩91| 五月婷伊人| 国产黄色大片| 婷婷五月AV| 婷婷九月激情| 久久久er热| 日本wwww在线| 91久久精品无码一区二区三区| 97干在线视频| 亚洲精品又粗又大又爽A片| 热99热9| 狠狠色丁香久久| 色婷久久| 天天色域综合网| 91色色色18| 97精品人人A片免费看| 婷婷六月五月天综合| 99riAV国产精品视频| 色五月婷婷久久| 天天爽天天摸人妻综合网| 国产操B视频| 国产美女无遮挡裸体毛片A片| 婷婷五月天开心激情网| 丁香婷婷啪啪| 婷婷五月丁香基| 婷婷久久久久| 色婷婷香蕉丁丁网| 狠狠五月激情丁香六月| 精国产品一区二区三区A片| 五月久视频| 99热免费网站| 91久久九九| 五月激情综合网| 激情五月色播五月| 天天做综合| 综合超碰熟| 性爱视频久久| 蜜桃人妻无码AV天堂三区| 婷婷五月深深的爱| 久久在线92| 北条麻妃九九九国产精品视频| 久久精品系列| www.五月丁香av| 国产超碰在线| 色婷亚洲| 日韩成人中文| 99热首页| 久久人妻视频| 狠狠狠五月婷婷六月丁香| 久九色| 五月婷婷九九久久| 艳妇野外情欲放荡HD| 99久久99九九九99九他书对| 狠狠操性爱av| 九九热只有精品6| 综合色影| 69久久久| 超碰狠狠干99| 99热97| 婷婷五月天AV在线| 99re热免费观看视频精品| 干亚洲天堂| 亚洲av成人在线| 五月天丁香欧美激情| 日本视频不卡123区| 99热9| 99色色| 五月草视频| 青青草婷婷综合五月| 久久这里只精品66| 97碰| 日熟女| 99综合免费视频| 日在线V视频在线播放| 天天五月丁香五月| 91AV婷婷| 99在线热视频| se色综合网| 91精品久| 99爱在线| 七月丁香五月婷婷在线| 久久久人妻| 激情五月综合网| 欧美va在线| 五月丁香激情啪啪| 五夜婷婷| 欧美日朝成人| 婷婷午夜激情| 91操在线视频| 色婷婷www| 99热播放| 大香蕉婷婷色| 九九热黄色| 伊人干综合| 99爱爱| 综合婷婷| 丁香五月五月婷婷| 99精品综合| 日本99久久| 六月丁香网| 99热在线观看| 亚洲第一成人无码A片| AA片在线观看视频在线播放| 国产肥白大熟妇BBBB视频| 青青草免费公开视频| 麻豆AV一区二区三区| 97很鲁在线视频| 中字幕视频在线永久在线观看免费| www色五月| 99热99色| 97啪啪| 四色99久久| 九九热99免费视频| 色婷婷av在线观看| www狠狠| 国产AV一区二区三区日韩| 这里有精品| 午夜成人av在线| 色婷婷性爱| 久久久精品AV| 色娸娸综合网| 久久香蕉网| 色欲日日躁| 五月婷婷丁香在线| 五月婷久久在线| 日本婷色| 26uuu欧美日本| 2018国产大陆天天弄| 日日夜夜狠狠| 色综合婷婷99| 免费国产视频| 亚洲第一精品网站| 婷婷五月天色播| 日韩欧美一级大黄网站| 女人高潮内射99精品| 成人综合网站| 五月婷婷9| 综合色五月| 婷婷五月天激情综合| 襙比视频| 婷婷成人视频| 99这里有精品| 色呦呦在线| 婷婷综合伊人| 思思99热这里只有精品| 深爱激情久久| 久久久久亚洲AV成人无码电影| 婷婷精品在线| 国精产品一区一区三区免费视频| 嘿嘿视频免费看9| 成人在线视频网| 天天日天天舔天天摸| 丁香五月天成人| 久久视频婷婷视频| 亚洲五月综合色播| 天天夜天天色天天| 久久精品系列| 亚洲色综合| 婷婷丁香91| 色色免费网站| 99热这里只有精品 搜| 婷婷午夜激情| 90色免费视频| 丁香五月激情网| 99精品视频免费观看,| 91碰碰视频| 激情小说色五月| 九九热9| 亚洲操人| 色亚洲激情| 中国女人内射6XXXXX| 激情六月丁香| 五月综合777| 亚洲综合色婷婷| 免费在线观看av网站| 人人爽人人射-美女久久久久久久久久-成人AV | 天天摸天天日天天舔| 狠狠干夜夜干| AA片在线观看视频在线播放| 1024婷婷综合久久五月天| 色婷婷亚洲在线| 五月婷婷六月丁香激情| 九九色色| 久久多色| 九九热这里只有精品6| 婷婷色影音天| 青青草原亚洲天堂| 欧美丁香婷婷五月天| 色欧美一级| 开心久久五月天| 丁香六月情| 丁香六月婷婷基地| 婷婷五月天伊人在线| 日本啪啪网| 色五月婷婷激情基地| 99re在线观看视频| 99久久6| www.91婷婷| 99久久婷婷精品视频| 国产99久久久| AV色婷婷| 婷婷五月中文字幕| 亚洲成人在线五月天| 4438亚洲欧美| 99久视频| 色色免费网站| 91精品91久久久中77777久久玖玖九九| 久久这里只| 九九精品热| 精品国产va久久久久| 五月亭亭六月天| 免费黄色片子| AAA久久| 黄页免费一级视频懂色| 丁香五月开心婷婷| 91九九九九九九| 丁香六月无码| 啪啪啪丁香五月| 五月丁香拍拍激情综合| www.狠狠| 丁香五月aV| 天天射夜夜骑| 青青草免费公开视频| 99 频99热国里只有精品| 久久精品99| 五月婷婷天天色| 免费视频WWW在线观看网站| 超碰在线成人| 色综合色色| 丁香六月 婷婷六月| 粉嫩AV久久一区二区三区| 婷婷丁香激情五月|