免费国产精品自在自线-91精品国产色综合久久久浪潮-99热久久免费频精品-国产精品国模在线观看-久久亚洲国产精品成人?V秋霞-久久国产一级A片免费播放-亚洲国产欧洲综合97久久-久久国产白嫩美女呻吟高潮

ARTICLE DETAIL

資訊詳情

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

Modbus TCP Server源碼解析:從寄存器模型到并發(fā)與排錯(cuò)實(shí)戰(zhàn)

Modbus TCP Server源碼解析:從寄存器模型到并發(fā)與排錯(cuò)實(shí)戰(zhàn) 簡介這是一份基于C實(shí)現(xiàn)的MODBUS TCP服務(wù)器源碼主要面向工業(yè)自動化領(lǐng)域的開發(fā)者用于快速搭建支持MODBUS TCP通信的服務(wù)端程序。源碼實(shí)現(xiàn)了MODBUS協(xié)議中常用的功能碼03讀取輸入寄存器/離散輸入與功能碼16寫多個(gè)保持寄存器覆蓋請求解析、應(yīng)答構(gòu)造和常見錯(cuò)誤處理流程可作為理解協(xié)議棧、學(xué)習(xí)TCP/IP網(wǎng)絡(luò)編程及進(jìn)行二次開發(fā)的基礎(chǔ)框架同時(shí)幫助理解MODBUS協(xié)議規(guī)范與報(bào)文交互機(jī)制。資源壓縮包共22個(gè)文件、約152KB以7個(gè)h頭文件與5個(gè)cpp源文件為主附帶Visual Studio工程配置sln、vcxproj、rc等整體結(jié)構(gòu)清晰便于在Windows環(huán)境下直接編譯調(diào)試。目前已有2173人學(xué)習(xí)/下載。通過研讀源碼開發(fā)者可以掌握從報(bào)文接收到響應(yīng)返回的完整實(shí)現(xiàn)思路并據(jù)此便捷地?cái)U(kuò)展線圈讀寫等更多功能碼適配智能能源管理、環(huán)境監(jiān)測、自動化產(chǎn)線等不同工業(yè)控制場景提升設(shè)備互聯(lián)與遠(yuǎn)程控制的開發(fā)效率。1. 為什么 MODBUS TCP SERVER 源碼值得翻現(xiàn)場最常見的尷尬是用現(xiàn)成的 Modbus 從站模擬器主站數(shù)據(jù)讀得干干凈凈等換成一版自己寫的服務(wù)端連接能建立、報(bào)文也發(fā)了寄存器卻永遠(yuǎn)返回零或者偶爾飄成亂碼。你面前只有一個(gè)黑匣子轉(zhuǎn)向現(xiàn)有工具又復(fù)現(xiàn)不了最后只能硬著頭皮把服務(wù)端源碼從頭到尾查一遍。這正是 MODBUS TCP SERVER 源碼的價(jià)值所在它不是拿來到處復(fù)制粘貼的模板而是你處理現(xiàn)場問題的最后一本底賬。這篇文章會從一份最小可運(yùn)行的服務(wù)端源碼講起把 Modbus TCP 的報(bào)文結(jié)構(gòu)、寄存器模型、并發(fā)處理和事務(wù)標(biāo)識拆清楚再把我在幾個(gè)設(shè)備聯(lián)網(wǎng)項(xiàng)目里遇到過的坑按“現(xiàn)象—原因—解決”寫成排查清單。適合兩類人一類是要把 Modbus TCP Server 集成到采集網(wǎng)關(guān)、邊緣盒子或上位機(jī)里的開發(fā)工程師另一類是天天跟 PLC、HMI、組態(tài)軟件對點(diǎn)表被未知從站行為反復(fù)折磨的調(diào)試工程師。讀完你至少能帶走兩樣?xùn)|西一套可以直接抄作業(yè)的源碼骨架一份按圖索驥的排錯(cuò)手冊。至于最后要不要用開源庫、要不要自己維護(hù)看完第三四章你自己就能拍板。2. 從協(xié)議到源碼MODBUS TCP SERVER 的最小骨架2.1 先看 7 字節(jié)頭事務(wù)、單元和長度怎么對齊寫服務(wù)端之前腦子里必須有一張固定的幀結(jié)構(gòu)圖否則后面所有字節(jié)偏移都會算錯(cuò)。Modbus TCP 的請求由 MBAP Header 和 PDU 組成。MBAP 固定 7 字節(jié)事務(wù)標(biāo)識符占 2 字節(jié)協(xié)議標(biāo)識符占 2 字節(jié)長度字段占 2 字節(jié)單元標(biāo)識符占 1 字節(jié)。事務(wù)標(biāo)識符用在同一個(gè)連接里把請求和響應(yīng)配對協(xié)議標(biāo)識符必須為 0表示這是 Modbus 協(xié)議長度字段表示單元標(biāo)識符加 PDU 一共還有多少字節(jié)單元標(biāo)識符在串口透傳網(wǎng)關(guān)里代表從站地址純 TCP 場景通常填 0 或 1。服務(wù)端最容易翻車的不是總字節(jié)數(shù)而是長度字段的計(jì)算口徑。請求頭里的 length 是“單元標(biāo)識符 1 字節(jié) PDU 長度”。也就是說服務(wù)端讀完 7 字節(jié)頭之后還要繼續(xù)讀 length-1 個(gè)字節(jié)才是完整的 PDU。很多新人直接把后續(xù)所有可讀字節(jié)當(dāng)成一幀收完在連續(xù)請求的場景下會把下一個(gè)請求的頭也吞進(jìn)去表現(xiàn)就是第一幀正常第二幀開始全部錯(cuò)位。下面這張表列出四個(gè)最常用功能碼的請求響應(yīng)格式實(shí)現(xiàn)的邊界判斷基本都圍繞它展開。功能碼含義請求 PDU響應(yīng) PDU0x03讀保持寄存器起始地址(2B) 寄存器數(shù)量(2B)字節(jié)數(shù)(1B) 寄存器值(NB)0x04讀輸入寄存器起始地址(2B) 寄存器數(shù)量(2B)字節(jié)數(shù)(1B) 寄存器值(NB)0x06寫單個(gè)寄存器地址(2B) 值(2B)地址(2B) 值(2B)0x10寫多個(gè)寄存器起始地址(2B) 數(shù)量(2B) 字節(jié)數(shù)(1B) 值(NB)起始地址(2B) 數(shù)量(2B)注意 Modbus 協(xié)議里的寄存器地址從 0 開始而組態(tài)軟件界面上往往顯示成 40001、40002這個(gè) 1 的偏移是上位機(jī)顯示層的事源碼里別跟著加。我在項(xiàng)目里見過服務(wù)端收到起始地址 0 卻去讀數(shù)組下標(biāo) 1最后每個(gè)點(diǎn)位都差一位。2.2 寄存器模型的取舍用哪種內(nèi)存結(jié)構(gòu)支撐讀寫Modbus 的 PDU 不關(guān)心數(shù)據(jù)來自數(shù)組、數(shù)據(jù)庫還是某個(gè)硬件寄存器服務(wù)端源碼真正的分水嶺在寄存器模型的組織方式。最直接的做法是把每種寄存器區(qū)域做成一個(gè)數(shù)組。保持寄存器用 16 位無符號整數(shù)地址連續(xù)讀寫都靠下標(biāo)索引。先初始化一塊長 100 的列表寫單個(gè)寄存器就更新第 n 個(gè)元素讀就按切片返回。這個(gè)模型跑通協(xié)議已經(jīng)足夠但它有個(gè)明顯缺點(diǎn)當(dāng)點(diǎn)位數(shù)量和業(yè)務(wù)邏輯變多每個(gè)功能碼分支都要復(fù)制一遍邊界判斷代碼很快會變得沒法維護(hù)。我建議的順序是先用簡單數(shù)組把服務(wù)端跑通再做數(shù)據(jù)訪問層抽象。不要一開始就上配置文件、多區(qū)域映射那會讓問題疊加。真實(shí)項(xiàng)目里常見的做法是維護(hù)一個(gè)點(diǎn)表配置每個(gè)條目包含起始地址、數(shù)量、讀寫權(quán)限和數(shù)據(jù)來源服務(wù)端在收到請求后根據(jù)配置動態(tài)查表。這個(gè)會在最后一章展開。選型方面還有另一條路直接用現(xiàn)成開源庫比如某開發(fā)者常用的 Python Modbus 庫它內(nèi)置了 Datablock 和協(xié)議解析上位機(jī)工具類項(xiàng)目用它非常省事。我當(dāng)時(shí)堅(jiān)持自己寫一遍是因?yàn)閮?nèi)核要移植到一個(gè)很小的實(shí)時(shí)系統(tǒng)里第三方庫依賴太重不如一套純 socket 代碼容易裁剪。這個(gè)選擇沒有標(biāo)準(zhǔn)答案關(guān)鍵看你的運(yùn)行環(huán)境是否允許引入外部依賴。2.3 最小源碼不依賴第三方庫的 Python server下面給出一份我裁剪過的最小實(shí)現(xiàn)只覆蓋讀保持寄存器和寫單個(gè)寄存器以及異?;匕?。它能讓你在本地立刻看到一個(gè)可交互的 Modbus TCP Server。import socket import struct import threading # 保持寄存器表地址從 0 開始長度 100 REG_HOLDING [0] * 100 REG_LOCK threading.Lock() def build_response(tid, unit, pdu): # MBAP 中 length 單元標(biāo)識(1) PDU 長度 length len(pdu) 1 return struct.pack(HHHB, tid, 0, length, unit) pdu def handle_client(conn): try: while True: mbap conn.recv(7) if not mbap: break tid, pid, length, unit struct.unpack(HHHB, mbap) if pid ! 0: break # 還需要讀取 length-1 字節(jié)的 PDU pdu b remain length - 1 while remain 0: chunk conn.recv(remain) if not chunk: return pdu chunk remain - len(chunk) func pdu[0] if func 0x03: # 讀保持寄存器 start, count struct.unpack(HH, pdu[1:5]) # 單次最多讀 125 個(gè)寄存器 if count 0 or count 125 or start count len(REG_HOLDING): resp build_response(tid, unit, bytes([0x83, 0x02])) else: with REG_LOCK: values REG_HOLDING[start:start count] payload bytes([count * 2]) for v in values: payload struct.pack(H, v) resp build_response(tid, unit, bytes([0x03]) payload) elif func 0x06: # 寫單個(gè)保持寄存器 addr, value struct.unpack(HH, pdu[1:5]) if addr len(REG_HOLDING): resp build_response(tid, unit, bytes([0x86, 0x02])) else: with REG_LOCK: REG_HOLDING[addr] value resp build_response(tid, unit, bytes([0x06]) struct.pack(HH, addr, value)) else: # 非法功能碼 resp build_response(tid, unit, bytes([func | 0x80, 0x01])) conn.sendall(resp) finally: conn.close() def start_server(ip0.0.0.0, port502): srv socket.socket(socket.AF_INET, socket.SOCK_STREAM) srv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) srv.bind((ip, port)) srv.listen(5) print(Modbus TCP Server listening on {}:{}.format(ip, port)) while True: conn, addr srv.accept() threading.Thread(targethandle_client, args(conn,), daemonTrue).start() if __name__ __main__: start_server()這段代碼有幾個(gè)值得圈出來的點(diǎn)。tid, pid, length, unit用HHHB一次拆出所有多字節(jié)字段都按網(wǎng)絡(luò)大端解析。build_response統(tǒng)一封裝 MBAP 頭每個(gè)分支不用各自拼長度從根上減少“響應(yīng)長度算錯(cuò)”的概率。REG_LOCK是必須加的因?yàn)槎嗫蛻舳司€程同時(shí)讀寫同一個(gè)列表不加鎖會出現(xiàn)數(shù)據(jù)交錯(cuò)現(xiàn)場表現(xiàn)是寄存器值莫名其妙歸零或者變成舊值。功能碼 0x03 的響應(yīng)里有“字節(jié)數(shù)”字段這是 01/02/03/04 共有的結(jié)構(gòu)漏掉之后主站會一直等到超時(shí)。異?;匕仨毎压δ艽a最高位置 1例如 0x03 變 0x83同時(shí)帶異常碼 0x02 表示非法數(shù)據(jù)地址。主站看到高位為 1 才會按異常處理直接回普通功能碼會讓主站把后面的字節(jié)當(dāng)成正常數(shù)據(jù)去解析必然錯(cuò)亂。啟動后用 Modbus Poll 或其他主站工具連接 502 端口讀起始地址 0、數(shù)量 10如果返回的數(shù)據(jù)比你預(yù)期少或者讀到亂碼先看是不是字節(jié)數(shù)字段和實(shí)際返回長度不一致。這是最小實(shí)現(xiàn)最容易踩的第一個(gè)坑后面避坑章節(jié)還會繼續(xù)展開。3. 源碼不只是收發(fā)事務(wù)標(biāo)識、并發(fā)和連接管理3.1 事務(wù)標(biāo)識符(TID)并發(fā)請求配對的關(guān)鍵MBAP 頭第一個(gè)字段是事務(wù)標(biāo)識英文縮寫 TID。在同一個(gè) TCP 連接里客戶端可以連續(xù)發(fā)送多個(gè)請求并不嚴(yán)格要求一問一答。服務(wù)端必須原樣回顯請求中的 TID客戶端才能把響應(yīng)和請求對應(yīng)起來。如果服務(wù)端把 TID 改成了自增序列客戶端就會出現(xiàn)響應(yīng)超時(shí)、請求錯(cuò)位。有些簡單的上位機(jī)工具并不校驗(yàn) TID但不校驗(yàn)不代表你可以隨便改。我用過的幾款主流組態(tài)軟件都會在協(xié)議棧里核對這個(gè)字段一旦發(fā)現(xiàn)對不上就把這條響應(yīng)丟棄。所以源碼里最保守的做法是在handle_client入口保存?zhèn)魅氲?tidbuild_response原樣帶回。有一點(diǎn)容易被忽略Modbus TCP 標(biāo)準(zhǔn)允許在同一連接上多路復(fù)用事務(wù)但很多設(shè)備端從站只支持串行處理。如果你的客戶端是同一連接并發(fā)發(fā)請求而你的服務(wù)端是一個(gè)線程連續(xù)阻塞讀取響應(yīng)自然是一個(gè)一個(gè)返回這時(shí)客戶端如果做了多事務(wù) pending就會認(rèn)為部分請求超時(shí)。服務(wù)端源碼要區(qū)分好“連接級并發(fā)”和“事務(wù)級并發(fā)”。最簡單的辦法是限制同一連接同一時(shí)刻只處理一個(gè)事務(wù)客戶端通常也會退化為串行。真正要支持事務(wù)級并發(fā)就得為每個(gè)連接維護(hù)一個(gè) pending 字典按 TID 找到等待的 writer 再回包復(fù)雜度會明顯上升。3.2 多客戶端連接線程池與 asyncio 的取舍最小源碼用threading.Thread對每個(gè)客戶端起一個(gè)線程。這在客戶端數(shù)量少的時(shí)候沒有問題五六個(gè)主站輪詢完全扛得住。但現(xiàn)場往往是多臺主站同時(shí)連接每臺還會建立多條連接線程數(shù)一旦跑到幾十上百系統(tǒng)上下文切換開銷會非常明顯服務(wù)端響應(yīng)延遲開始抖動。常見的替代方案有兩個(gè)。第一是線程池用ThreadPoolExecutor限制最大并發(fā)線程數(shù)。因?yàn)槊總€(gè)連接的處理函數(shù)是一個(gè)長循環(huán)會一直占住一個(gè)線程所以線程池大小嚴(yán)格意義上是“最大并發(fā)連接數(shù)”不是“每秒能處理的請求數(shù)”。超出的連接會在 listen 隊(duì)列里排隊(duì)如果 backlog 太小新連接會直接被內(nèi)核拒絕。配合線程池一定要做空閑超時(shí)比如 30 秒沒收到幀就關(guān)閉連接否則一個(gè)斷開的客戶端沒被發(fā)現(xiàn)線程池里就少了一個(gè)可用的線程。第二是 asyncio 單線程事件循環(huán)適合連接多、每連接流量小、寄存器響應(yīng)快的場景。但 asyncio 有個(gè)致命禁忌業(yè)務(wù)代碼里不能出現(xiàn)任何阻塞調(diào)用比如time.sleep、同步數(shù)據(jù)庫查詢、文件鎖。一旦阻塞所有客戶端的請求一起卡住。用 asyncio 實(shí)現(xiàn) Modbus TCP Server 時(shí)讀取一幀的標(biāo)準(zhǔn)寫法是先讀 7 字節(jié)頭再根據(jù)長度字段用readexactly(length - 1)把剩余部分讀夠不要手動拼包因?yàn)?Modbus 幀邊界是自描述的長度字段就是最好的拆包依據(jù)。下面是 asyncio 服務(wù)端處理連接的核心骨架保留了 MPAB 讀取邏輯import asyncio import struct async def handle_connection(reader, writer): try: while True: mbap await reader.readexactly(7) tid, pid, length, unit struct.unpack(HHHB, mbap) if pid ! 0: break pdu await reader.readexactly(length - 1) # 按功能碼構(gòu)造響應(yīng) pdu邏輯同第二章節(jié) resp build_response(tid, unit, pdu) writer.write(resp) await writer.drain() except (asyncio.IncompleteReadError, ConnectionResetError): pass finally: writer.close() await writer.wait_closed()這里的關(guān)鍵參數(shù)是readexactly它要么讀滿指定字節(jié)要么拋異常絕不會出現(xiàn)少讀半個(gè)數(shù)據(jù)包的情況。缺點(diǎn)是一旦客戶端發(fā)了一個(gè)不完整的頭服務(wù)端會一直等下去所以必須在asyncio.wait_for里包一層超時(shí)。不要小看這個(gè)超時(shí)真實(shí)網(wǎng)絡(luò)環(huán)境里丟包后客戶端重傳服務(wù)端如果沒有超時(shí)機(jī)制連接會一直掛著慢慢耗盡系統(tǒng)文件描述符。3.3 長連接 vs 短連接哪種現(xiàn)場更常見Modbus TCP 設(shè)計(jì)默認(rèn)是長連接。真正的 PLC 主站會保持連接到從站周期性地輪詢寄存器斷線后還會自動重連。服務(wù)端如果處理完一次請求就關(guān)閉連接主站每個(gè)周期都要重新建連現(xiàn)場會出現(xiàn)“數(shù)據(jù)刷新慢、狀態(tài)經(jīng)常斷”的假象。短連接場景主要出現(xiàn)在 Web 后臺測試、臨時(shí)腳本或者需要快速釋放端口的工具中。做服務(wù)端源碼時(shí)要兩種都支持但不要主動關(guān)閉長連接。如果你確實(shí)需要回收空閑資源把空閑超時(shí)設(shè)置得盡量長至少 60 秒以上如果主站輪詢周期本身就長要考慮把這個(gè)超時(shí)再放大。還有一個(gè)常被忽略的點(diǎn)半開連接?,F(xiàn)場網(wǎng)絡(luò)抖動之后客戶端已經(jīng)不在但服務(wù)端的recv還一直在阻塞它根本不知道對方已經(jīng)消失。解決方法是給每個(gè)連接設(shè)置 socket 超時(shí)conn.settimeout(60)超時(shí)后關(guān)閉連接并記錄日志。這一步是 demo 代碼和生產(chǎn)級代碼真正的分界線。某些系統(tǒng)里還需要配合 TCP keepalive讓內(nèi)核層探測對端是否存活但 keepalive 默認(rèn)探測周期很長不能替代應(yīng)用層超時(shí)。4. 參數(shù)與配置讓 MODBUS TCP SERVER 源碼跑得穩(wěn)4.1 必調(diào)參數(shù)超時(shí)、緩沖區(qū)、地址范圍與端口把源碼從“能跑”推向“能扛現(xiàn)場”無非是把下面這幾個(gè)參數(shù)調(diào)成符合業(yè)務(wù)的數(shù)值。參數(shù)推薦值作用調(diào)大/調(diào)小的影響socket 超時(shí)30-60s檢測半開連接太小會讓慢周期主站誤認(rèn)為斷線太大浪費(fèi)連接資源recv 緩沖區(qū)2-8KB接收多幀時(shí)緩存Modbus 單幀小于 260B太大并不會提升性能監(jiān)聽 backlog5-10未 accept 的連接隊(duì)列太小高并發(fā)會丟連接太大占用系統(tǒng)內(nèi)存寄存器區(qū)長度按點(diǎn)表實(shí)際越界返回異常碼設(shè)成 65536 沒有任何收益反而放寬了越界風(fēng)險(xiǎn)最大連接數(shù)按設(shè)備性能保護(hù)服務(wù)不被打爆超過可以拒絕新連接返回日志字節(jié)序big-endian寄存器默認(rèn)大端改成小端會直接造成數(shù)據(jù)翻倍端口默認(rèn)是 502Linux 下低于 1024 的端口需要 root 權(quán)限很多開發(fā)環(huán)境會先用 1502 調(diào)試上線再映射到 502。如果你用 Docker 部署容器內(nèi)的 502 可以映射到宿主機(jī)的 1502不影響協(xié)議本身。SO_REUSEADDR一定要在 bind 之前設(shè)置否則服務(wù)端程序重啟后會因?yàn)橹暗?TIME_WAIT 狀態(tài)占用端口而失敗。這個(gè)選項(xiàng)不會像某些博客講的那樣“解決并發(fā)連接被 bind 拒絕”的問題它只是允許重用地址避免快速重啟時(shí)端口被占用。4.2 功能碼的邊界03/04/06/16 怎么實(shí)現(xiàn)與限制Modbus TCP 的 PDU 理論最大長度是 253 字節(jié)這一個(gè)數(shù)學(xué)約束決定了很多功能碼的數(shù)量上限。讀保持寄存器 0x03 和讀輸入寄存器 0x04 單次最多讀 125 個(gè)寄存器因?yàn)槊總€(gè)寄存器 2 字節(jié)125 個(gè)就是 250 字節(jié)加上功能碼和字節(jié)數(shù)正好 252卡在 253 以內(nèi)。寫多個(gè)寄存器 0x10 單次最多寫 123 個(gè)因?yàn)檎埱罄镞€有起始地址和數(shù)量留給數(shù)據(jù)的空間更少。很多從站源碼沒有做這個(gè)限制收到 count200 的請求時(shí)直接越界訪問列表并拋異常連接直接斷掉。主站看到連接斷開通常會連續(xù)重試然后報(bào)告“從站無響應(yīng)”。正確的做法是像第二章節(jié)代碼里那樣把邊界判斷放在任何數(shù)據(jù)處理之前如果 count 超過上限就返回異常碼 0x02 非法數(shù)據(jù)地址而不是讓程序崩潰。06 寫單個(gè)寄存器是最簡單的不存在批量上限問題但要處理地址越界。有些主站用 06 寫單個(gè)設(shè)置項(xiàng)時(shí)起始地址正好是點(diǎn)表末尾你如果只判斷addr len(REG_HOLDING)就沒有給“最后一個(gè)合法地址”留空間。常規(guī)寫法是addr len(REG_HOLDING)對應(yīng)數(shù)組下標(biāo) 0 到 len-1 合法。01 和 02 線圈/離散輸入功能碼在現(xiàn)場也很常見。線圈是 bit 存儲讀取 2000 個(gè)線圈需要 250 字節(jié)數(shù)據(jù)正好是 PDU 允許的極限。如果只實(shí)現(xiàn)了寄存器客戶端發(fā) 01 功能碼就會收到 0x01 異常。大多數(shù)設(shè)備端會同時(shí)實(shí)現(xiàn) 01/02/03/04因?yàn)榻M態(tài)軟件默認(rèn)要把所有類型都讀一遍。4.3 錯(cuò)誤處理異常碼返回與日志Modbus 異常碼總共就那么幾個(gè)0x01 非法功能碼、0x02 非法數(shù)據(jù)地址、0x03 非法數(shù)據(jù)值、0x04 從站設(shè)備故障。返回異常時(shí)必須把功能碼最高位置 1。比如 0x03 變成 0x830x06 變成 0x86。最高位沒有置 1 的響應(yīng)會被主站按正常數(shù)據(jù)處理這是現(xiàn)場排查時(shí)最難發(fā)現(xiàn)的錯(cuò)誤之一因?yàn)閳?bào)文結(jié)構(gòu)看起來完整實(shí)際內(nèi)容全是錯(cuò)位數(shù)據(jù)。日志不要貪多。每個(gè)連接記錄 TID、功能碼、起始地址和數(shù)量就夠了寄存器內(nèi)容只有在異常時(shí)才打印。我見過有人把每個(gè)請求的完整十六進(jìn)制都打進(jìn)日志結(jié)果服務(wù)端跑一天日志文件幾個(gè) GB真正想看關(guān)鍵信息的時(shí)候全被刷沒了。生產(chǎn)環(huán)境里建議加一個(gè)開關(guān)默認(rèn)開“請求摘要日志”級別 INFO調(diào)試時(shí)開“詳細(xì)報(bào)文日志”級別 DEBUG。抓包工具能覆蓋一部分問題但服務(wù)端日志能看到“程序內(nèi)部認(rèn)為哪里越界”這是 Wireshark 看不到的。5. 避坑MODBUS TCP SERVER 的常見故障排查5.1 現(xiàn)象請求一多寄存器值就被置零現(xiàn)象是單個(gè)連接單次請求都正常主站并發(fā)輪詢或者頻繁寫操作之后某個(gè)寄存器開始變成 0再過一會又恢復(fù)。原因通常是兩個(gè)一是多線程同時(shí)寫同一個(gè)寄存器數(shù)組沒有加鎖Python 里雖然 GIL 保證了單個(gè)字節(jié)碼指令的原子性但列表切片和賦值并不是整體原子操作兩個(gè)線程交錯(cuò)時(shí)會讀到舊值二是服務(wù)端讀取 PDU 時(shí)沒有嚴(yán)格按 length 字段接收用了一次不完整的 recv導(dǎo)致下一幀的偏移量出錯(cuò)寫入請求的地址亂套。解決方法是給寄存器數(shù)據(jù)加鎖并在解析幀時(shí)嚴(yán)格按“先讀 7 字節(jié)頭再循環(huán)讀夠 length-1 字節(jié)”來收包。第二章節(jié)代碼里的while remain 0就是這個(gè)目的。不要相信一次 recv 能拿到完整 PDU尤其在本地回環(huán)之外的以太網(wǎng)環(huán)境。5.2 現(xiàn)象連接不釋放導(dǎo)致端口耗盡現(xiàn)象是服務(wù)端運(yùn)行一段時(shí)間后新的客戶端連接全部失敗用netstat能看到大量 TIME_WAIT 或者 ESTABLISHED 狀態(tài)的連接堆積程序日志里全是 bind 或 accept 相關(guān)的報(bào)錯(cuò)。原因是對端異常斷開時(shí)服務(wù)端 recv 沒有返回一直阻塞或者客戶端主動關(guān)閉時(shí)服務(wù)端沒有進(jìn)入 close 流程。每個(gè)堆積連接占一個(gè)文件描述符Linux 默認(rèn)進(jìn)程最大文件描述符是 1024很快就會被耗盡。解決方法是給每個(gè)連接設(shè)置超時(shí)時(shí)間conn.settimeout(60)在handle_client里把 socket 超時(shí)異常統(tǒng)一捕獲并關(guān)閉連接。同時(shí)可以在 accept 后設(shè)置 TCP keepalive但 keepalive 默認(rèn)參數(shù)在 Linux 下是 2 小時(shí)不適合短周期檢測需要配合套接字選項(xiàng)調(diào)整探測時(shí)間。最穩(wěn)的還是應(yīng)用層超時(shí)加線程回收。5.3 現(xiàn)象字節(jié)序反了明明是 1 讀出來是 256現(xiàn)象是寫一個(gè)寄存器值 1主站讀出來是 256寫 0x0102讀出來 0x0201。原因是 Modbus 寄存器默認(rèn)大端高字節(jié)在前。如果用本地字節(jié)序的struct.pack(H, value)在 x86/ARM 小端環(huán)境里會把低字節(jié)放到內(nèi)存前面報(bào)文變成低字節(jié)在前主站按大端解析正好反了。解決方法是所有多字節(jié)字段統(tǒng)一用H、I不要用裸的H或I。Python 的struct默認(rèn)用本地字節(jié)序機(jī)器不同行為不同最容易踩。排查時(shí)寫一個(gè)固定值 0x1234 到寄存器讀回來看字節(jié)排列能立刻確認(rèn)是不是字節(jié)序問題。5.4 現(xiàn)象模擬器可以讀真實(shí) PLC 請求超時(shí)現(xiàn)象是 Modbus Poll、模擬主機(jī)都能正常讀寫換成某品牌 PLC 做主站后服務(wù)端日志顯示收到了請求但主站一直報(bào)超時(shí)或者間歇性失敗。原因通常是真實(shí) PLC 會一次性建立多個(gè)連接并在一個(gè)連接里連續(xù)發(fā)送多個(gè)請求還有可能是 PLC 發(fā)送了你沒有實(shí)現(xiàn)的功能碼比如 0x10 寫多個(gè)寄存器而服務(wù)端返回了非法的異常碼主站協(xié)議棧直接放棄重試。解決方法是先抓包看 PLC 實(shí)際發(fā)出來的請求是什么樣子。重點(diǎn)看三個(gè)字段TID 是否在同一個(gè)連接上遞增、功能碼是什么、起始地址和數(shù)量是多少。抓不到包時(shí)在服務(wù)端日志里打印收到的原始 PDU 十六進(jìn)制哪怕不打完整報(bào)文也要打功能碼和長度。很多問題時(shí)隱性的主站只報(bào)超時(shí)不會告訴你它發(fā)送了什么。5.5 現(xiàn)象異步框架里用阻塞讀導(dǎo)致整個(gè)服務(wù)卡死現(xiàn)象是用 asyncio 實(shí)現(xiàn)的服務(wù)端在低并發(fā)時(shí)正??蛻舳诉B接一多整體響應(yīng)延遲飆升甚至所有請求都沒反應(yīng)。原因是在異步回調(diào)里用了同步的time.sleep、同步 socket 操作或者 CPU 密集型的大循環(huán)。asyncio 是單線程事件循環(huán)一個(gè)阻塞調(diào)用會停掉整個(gè)循環(huán)其他連接即使早就準(zhǔn)備好了也無法被處理。解決方法是所有耗時(shí)操作放進(jìn)線程池比如await asyncio.to_thread(do_heavy_work, data)讀取網(wǎng)絡(luò)數(shù)據(jù)必須用reader.readexactly不要用socket.recv。同時(shí)給每個(gè)請求的處理加上超時(shí)保護(hù)避免某個(gè)客戶端不發(fā)完數(shù)據(jù)時(shí)整個(gè)事件循環(huán)被readexactly永久占住。這個(gè)坑最容易在“把原來 thread 版改成 asyncio 版”的時(shí)候出現(xiàn)因?yàn)楹芏啻a只是換了個(gè)殼內(nèi)部還是一堆阻塞函數(shù)。6. 從源碼到交付寄存器映射、抓包驗(yàn)證和壓測6.1 把寄存器表變成配置而不是把地址寫死在 if 里第二章節(jié)的源碼用的是一個(gè)固定長度列表適合跑通協(xié)議。真正到一個(gè)有幾十個(gè)點(diǎn)位、不同寄存器代表溫度、轉(zhuǎn)速、狀態(tài)的現(xiàn)場再在 if 分支里手寫地址就很痛苦了。我一般會把點(diǎn)表抽成一個(gè)配置結(jié)構(gòu)每個(gè)數(shù)據(jù)區(qū)包含起始地址、長度、讀寫權(quán)限、當(dāng)前值來源函數(shù)。比如溫度寄存器由傳感器線程更新設(shè)定值寄存器由 Modbus 寫請求更新。服務(wù)端收到請求后先按功能碼找到對應(yīng)的數(shù)據(jù)區(qū)再做邊界判斷。這樣做的好處是現(xiàn)場點(diǎn)位調(diào)整時(shí)只改配置不重新編譯。點(diǎn)表結(jié)構(gòu)可以用一個(gè)簡單的 Python 類來表示核心目的是讓“地址—數(shù)據(jù)來源”的映射一目了然。不要在這里過度設(shè)計(jì)第一個(gè)版本用 dict 加回調(diào)函數(shù)就足夠。6.2 抓包驗(yàn)證是源碼調(diào)試的第一現(xiàn)場Wireshark 是排查 Modbus TCP Server 最直接的證據(jù)來源。過濾條件寫tcp.port 502逐幀展開 MBAP 和 PDU立刻能看到長度字段是不是正確的、功能碼有沒有回執(zhí)、異常碼高位有沒有置 1。我最常用的驗(yàn)證套路是先寫一個(gè)寄存器值 0x0102再讀回來。如果抓包看到的值是 0x0102說明字節(jié)序和收發(fā)都正常如果看到 0x0201不用懷疑就是字節(jié)序問題。然后再測邊界讀起始地址 0、數(shù)量 125成功改成數(shù)量 126應(yīng)返回 0x83 0x02。這個(gè)用例能同時(shí)驗(yàn)證正常路徑和異常路徑。Wireshark 里如果看到 Malformed 標(biāo)記基本是長度字段和實(shí)際數(shù)據(jù)長度不匹配。此時(shí)不要急著改程序先看這一幀的 Byte Count 和后續(xù)實(shí)際字節(jié)數(shù)差了幾個(gè)。常見原因是在響應(yīng)里多寫了地址或者少算了 unit 標(biāo)識符長度。6.3 給源碼加一個(gè)最小壓測腳本交付之前我會用一個(gè)幾十行的腳本做一次并發(fā)冒煙。下面是一個(gè)用 Python 線程池模擬多主站的簡單框架每一線程建立獨(dú)立連接連續(xù)執(zhí)行寫后讀統(tǒng)計(jì)成功率import socket import struct import threading def modbus_read(conn, start, count): # 構(gòu)造 03 請求 tid 1 pdu struct.pack(BHH, 0x03, start, count) mbap struct.pack(HHHB, tid, 0, len(pdu) 1, 1) conn.sendall(mbap pdu) header conn.recv(7) tid2, pid, length, unit struct.unpack(HHHB, header) data b while len(data) length - 1: data conn.recv(length - 1 - len(data)) return data def worker(ip, port, errors): try: conn socket.create_connection((ip, port), timeout3) for i in range(100): resp modbus_read(conn, 0, 10) if len(resp) 22: # 1字節(jié)功能碼 1字節(jié)數(shù)量 20字節(jié)數(shù)據(jù) errors.append(short response) break conn.close() except Exception as e: errors.append(str(e)) threads [] errors [] for i in range(20): t threading.Thread(targetworker, args(127.0.0.1, 502, errors)) t.start() threads.append(t) for t in threads: t.join() print(errors:, len(errors))這個(gè)腳本不對響應(yīng)內(nèi)容做過深校驗(yàn)它主要看兩件事多連接并發(fā)時(shí)會不會崩、會不會出現(xiàn)短包。如果 errors 數(shù)量逐漸增長下一步就去查服務(wù)端 backlog 和線程數(shù)如果短包頻繁極大概率是響應(yīng)長度字段寫錯(cuò)。6.4 一個(gè)長期受用的交付習(xí)慣這套源碼骨架我在不同項(xiàng)目里打磨過很多輪真正讓它穩(wěn)定下來的不是代碼技巧而是“每跑一個(gè)用例都留證據(jù)”的習(xí)慣。本地能連通只是第一步邊界返回、異常碼、并發(fā)讀寫、抓包一致性這四個(gè)驗(yàn)證點(diǎn)缺一不可?,F(xiàn)在每接到一個(gè)要集成 Modbus 從站的活我都會先花一小時(shí)把最小服務(wù)和壓測腳本搭起來再開始談業(yè)務(wù)點(diǎn)表。源碼的價(jià)值不在第一次運(yùn)行通過而在后續(xù)任何一次故障里你都能翻開它快速定位到那幾行可疑的判斷。希望幫到你。本文還有配套的精品資源點(diǎn)擊獲取
返回列表
PREV
查看更多資訊
NEXT
返回資訊列表
综合色播| 狠狠婷婷色综合| 91色逼| 五月天大香蕉| 婷婷五月天激情开心网| 婷婷色香六月综合激情| 日本久久婷| 婷婷丁香视频在线观看免费| 97黑人精品区| 色约约视频一区二区三区四区五区| 91九色熟女| 丁香五月天在线直播观看| 五月婷婷精品视频| 91人妻九色大屁股| 亚洲乱码日产精品BD| 亚洲午夜电影| 婷婷五月天天爽| 呦呦AV| 婷婷丁香五月天影院 | 影音先锋天天日| 九九成人视频| 色播五月丁香| 综合色网站| 免费视频WWW在线观看网站| 丰满熟女人妻一区二区三| 99色色热| 五月综合视频在线| 爱之国产色情综合| 丁香五月天婷婷久久| 久99视频在线观看| 超碰成人在线观看| 九九九九综合| 99色色爰| 色波激情五月天| 色情婷婷。| 久久婷婷五月天大香蕉| 99热午夜精品| 一区二区三区四区牛| 99国产精品久久久久久久久久久 | www.狠狠色.com| 丁香色六月婷婷| 婷婷.com| 久久月天堂| 插插网爽妇五月丁香| 超碰激情网| 影音先锋 一区| 日韩另类| 欧美丁香五月| 色狠狠综合| 亚洲乱码精品久久久久..| 99热精品在线观看| 激情综合九月| 9色在线| 六月婷婷啪啪| 91日本在线| 天天爱天天狠天天透| 欧美色色色色色色色| 99热这里只有精品23| 六月丁香激情综合网| 久久婷婷五月综合色奶水99啪| 六月婷婷狠狠做| 婷婷视频网| 久久电影4399| 婷婷久久五月天亚洲欧美国产日韩在线观看 | AⅤ色区| 伊人综合网4| 色色精品色| 五月婷五月婷伊人伊人五月婷| 天天肏视频| 五月婷网| 日日日影院| 岛国av电影网站| 亚洲激情五月丁香久久久久| AA丁香综合激情| 91黄操| 天天干天天操天天拍| 五月天开心网| 亚洲成人综合网在线免费观看| 九色综合五月天婷五月| 色 免费网站视频| 日本人妻丁香婷婷久久寝取熟女五月| 综合色图婷婷| 97婷婷丁香| 激情综合五月| 九九99视频| 色色AV色色色东莞| 少妇AB又爽又紧无码网站| 疯狂做受XXXX高潮A片| 99热香港| 五月天六月丁香| 思思精品久久艹| 六月综合在线| 成人无码精品1区2区3区免费看| 婷婷五月激情基地| 五月婷视频久久| 婷婷五月情色| 激情久久综合| 99免费青青蜜臀| 人人操91| 99在线观看精品视频| 色色色色五月| 99热这里都是精品| 五月综合色| 热久久999| 五月丁香啪啪综合| 色丁香五月| 激情五月天色色网| 激情五月天婷婷色色色色色色色色色色色| 777久久精品| 久久久久久久久久人妻| 五月天成人免费视频| 狠狠色丁香乆乆| 久草五月婷婷| 色色五月婷婷久久| 丁香社92视频| 99热这里只有免费| 疯狂做受XXXX高潮A片| 91干网| 成人操呦av| 久久婷婷六月综合| 67194线路二在线观看| 婷婷四色五月| 激情中文在线| 激情久久 婷婷| 五月丁婷婷| 在线婷婷| 五月丁香91| 99愛国产| 超碰啪啪网| 99这里有精品久久97| 吉澤明步Av一區二區| www99热| 538任你爽视频不一样的| 婷婷性爱无码视频| 超碰狠狠干99| 婷婷丁香视频| 国产69久久久欧美黑人A片| 99色色网| 成人va在线播放| 激情五月天综合网| 欧美婷婷丁香五月社区| 人人97碰| 色情五月婷婷| 秋霞午夜理论| 俺去也五月| 99,色| 亚州操操| 成人婷99最新| 九九热视频这里只有精品| 激情伊人网| 色综合色色| www.wuyuetian啪啪| 婷婷五月天Av| 97色射| 六月丁香激情综合| 中文字幕无码成人电影| 婷婷娌伦网| 日本偷拍九九九| 五月婷婷香蕉| 激情婷婷网| 色爱亚洲| 九九综合精品| 国产精品久久久爽爽爽麻豆色哟哟| 婷婷五月激情网站| 性av| 天天色天天日天天舔| 婷婷五月综合中文字幕| 色五婷婷在线视频| 超碰激情网| 97色久| 97碰在线| 岛国在线观看91| 天天天天做夜夜夜夜做| 五月丁香激| 99热青青草| 天天射美女| 亚洲热视频| 婷婷色女| 五月综合激情图片| 99操视频| 天天操天天日天天爽| 丁香五月婷婷av影院| 五月丁香狠狠地噜噜噜噜| 91久久久久| 亚洲成人在线五月天| 免费观看日韩成人av| 天天综合网站| 99热精品10| 色婷婷中文| 五月亭亭性| 婷婷五月天六点丁香五月| 久热91| 婷五月丁香| 色色色色色日韩午夜激情| 日日操天天操| 丁香五月天激情小说| 久久sp免费视频| 91九色丨国产丨爆乳| 九九色逼| 久婷婷色| www.夜夜爱.com| 色激情五月| 青青操avbb| 婷婷五月丁香激情图片 | 在线1青婷| 2017人人操| 五月天成人综合| 婷婷开心综合人妻小说网址| 99操视频| 中文字幕欧美久久| 六月婷婷综合网2| 能看的av| 色婷婷狠狠干芒果TV| 丁香六月激情四射| 99热 在线播放| 久久9视频| 看片视频在线免费日产在线看| 噜综合| 色五月色情| 丁香五月香蕉| 91婷婷色 | 久久久五月婷婷| 亚洲第一成人无码A片| 影音先锋91在线资源站| www.婷婷五月天| 日韩aaa| 美女100%露全身无挡网站| 天久久久久| 少妇人妻偷人精品无码视频新浪| 久久激情五月婷婷| 激情av| 99国产这里只有精品| 久久五月天精品视频| 男人天堂AV在线一区二区| 亚洲精品久久久久AV无码| 久久天天| 五月丁香六月激情在线| 色九月综合| 97香蕉碰碰人妻国产欧美| 综合五月天| 激情婷婷五月天在线观看| www色婷婷| 大香婷婷| 91久久久久久久91| 9久9久| 韩国97天堂| 婷婷丁香六月| 国外亚洲成AV人片在线观看| 亚洲乱码日产精品BD| 激情图片五月天| 91人人爽狠狠狠| 开心婷婷中文字幕| 日本在线99| 五月婷婷AV| 色99热| 婷婷五月丁香久久| 五月天久久综合婷婷丁香| 婷婷色香六月综合激情| 国产五月婷| 这里只有视频精品| 五月丁香六月婷婷久久久综合| 另类五月婷婷| 丁香婷婷六月天| 日韩成人五月天| 激情丁香久久| 丁香五月,激情五月,深爱五月| 五月情综合| 婷婷 激情 五月| 99热日韩这里只有精品| 色综合网综合| 久色大| 91婷婷丁香五月| 精品爆操| 色婷婷成人做爰A片免费看网站| 亚洲人人操| 国自产拍偷拍精品啪啪一区二区| 色综合99无码 | www.99热| 国产精产国品一二三在观看| 成人 九九九九| 国产亚洲av片| 97色在线| 五月丁香青草综合啪啪| 色综合伊人网| www.色婷婷| 欧美色五月| 99视频| 婷婷丁香六月天激情四射网| 黄色一级影片| 成人婷婷深爱综合网| 色狠狠六月| 亚洲色 视频| 色天五月天在线观看视频| 色欲午夜无码久久久久久张津瑜| 97香蕉碰碰人妻国产欧美| 疯狂做受XXXX高潮A片| 操精品9| 色色日本欧美| 色婷婷婷婷成人网| 超碰在线超碰| 婷婷D区| 日韩大片艹艹| 久久视频这里都是精品| 99视频在线精品| 色色色色色色网站| 亚洲国产网址| 久久小视频免费| 丁香婷婷六月在线资源观看| 夜夜夜夜夜操| 日本毛片内射| 热99这里只有精品视频| 成人精品在线| 日本三级色| 国产xxxxx在线观看| 天天色综合网1| 五月天婷婷影院| 欧美人与性动交CCOO| 国产a视频| 丁香五月1页| 狠狠干思思热| 欧美性生交XXXXX无码小说| 九九久99免费视频| 丁香六月 人妻| 婷婷在线视频| 久久女人九九| 色婷丨日丨天丨综合久久| 色婷婷国产精品综合在线观看| 成人片在线播放| 婷婷久久图片| 操大屄五月天视频| 五月婷久久| 91狠狠综合网| 久久玖玖综合| 超碰1999| 五月丁香色色色| 插插插丁香五月婷婷| 26UUU精品一区二区| 五月丁久久| 国产一级片| 婷婷五月天天天| 婷婷综合婷婷| 五月丁香婷婷中文网| 色综合色色色| 99精品热视频只有精品10| 五月丁香六月玩女人| 亚洲中字AV电影在线网站| 99爱视频精品| 天天操天天操天天操天天操天天操| 亚洲综合欧美色丁香婷婷888月图片 | 亚洲视频二区| 婷婷午夜精品久久久| 九九精品婷| 久久99久久99精品免观看软件 | AV无码免费| WWW.99视频| 丁香五月婷婷少妇| 九九热免费视频| 欧美日韩国产成人在线| 五月激情婷婷在线| 欧美日韩成人在线网| 激情五月婷婷丁香| 丁香六月婷婷综合啪啪| 97资源碰碰| 久热91精品| 亚韩在线视频| 色情五月婷婷| 538在线精品| 深爱丁香网| 99热综合| 激情五月天www| 五月婷婷六月爱| 色色热| 婷婷丁香视频在线观看免费 | 天天日天天干天天操| 五月丁香综合啪啪| 69超碰在线| 思思久热6| www色哟哟| 五月开心深爱激情网| 久久性爱激情| 久9热在线视频| 亚州色婷婷| 五月天色丁香| 涩涩婷婷五月| 久久婷婷内射| 国产成人精品亚洲线观看| 激情婷婷丁香色情五月天| 老妇六区| 99久久亚洲国产| 99免费在线视频| chaopeng在线人人| 91视频一起草| 色久婷婷网| 91色色五月天| 99热播放| 天天射综合网天天插| 新激情婷婷| 99热6色| 国产精典视频在线观看| 国外亚洲成AV人片在线观看| 狠狠色大香蕉| 日日干夜夜撸夜夜骑| 91国产精品视频播放| 五月天激情网图片| 日本婷婷综合精品| 综合99视频| 激情婷婷六月天| 日韩小视频在线99| 九九色热| 一操久久| 婷婷天天插天天爱| 国产91在线视频| 男人天堂99| 婷婷五月AA五月在线| 在线成人av播放| 亚洲男女激情| 99色热视频在线| 日操| 天堂色婷婷| 国产成人精品一区二三区熟女在线| 五月天综合影院| 亚洲区视频| 人五月天婷婷喷水| 久久性爱视频| 婷婷五月天堂| 天天久| 26uuu.| 99操免费视频| 涩婷婷视频快播人妻| 国产这里只有精品| 六月婷婷综合激情| 日本色色色| 色五月之第四色| 久久免费丁香| 久播影院免费观看电视剧大全最新网| 在线观看熟女少妇| 性视频久久| 九色亚洲| 欧美叉叉叉BBB网站| 99噜噜| 69色色视频| 99极品视频| 色婷婷综合亚洲| 丁香五月激情啪啪综合| 国产精产国品一二三在观看| 久久婷婷五月| 久操大香蕉| 狠狠摸狠狠摸| 欧美婷婷精品激情| 啪啪亚洲综合| 丁香五月亚洲| 五月丁香六月婷婷综合网缴情| 色婷婷91激情小说| 久久色频| 99热 免费| 亚洲操逼网| 丁香五月激情啪| 婷婷综合一二三| 97亚洲精品| 五月天天丁香婷婷| 91干婷婷| 9久热在线精品| 九一娱乐在线观看视频| 91久久国产自产拍夜夜91久久精品文字>91麻豆精品国产 | 大香蕉人妻| 久久久久妻| 9久久AV| 色五月综合97| www.婷婷,com| 黄网在线免费观看| 天天射夜夜爽| 五月综合777| 婷婷瑟五月天久久综合| www.lingjunshare.com| 5月婷婷五月天| 精品五月天| www.五月.com| 中美日韩成人在线| 色狠狠综合| 女人高潮内射99精品| 99啪啪| 国产午夜精品AV一区二区麻豆| 99国产精品久久久久久久久久久| 国产操B| 97超喷视频在线观看| 99久免费视频| 永久无码色| 天天人人综合| 五月婷婷综合潮喷| 五月天激情啪啪| 另类图片色五月| 五月激情婷婷在线| 婷婷丁香18| 丁香六月成人网| 超碰在线观看9| 丁香五月激情婷婷视频| 天天干天天玩天天夜天天射天天操天天日蜜臀少妇| 九九热视频免费| 五月天开心婷婷激情网站| 五月婷婷久久大香蕉| 天天爽天天干| 91av色色乱视频| 婷婷综合五月天| 激情综合网五月天天| 区区欧美你爱| 婷婷丁香在线| 人妻免费网站| 成人看片网站| 色色综合网络| 色无码| 亚洲人操亚洲人| 婷婷五月天综合久久| 99在线观看视频蜜臀| 懂色AⅤ| 国产激情视频在线观看| 久热精品免费视频4| WWW·色色色·COM| 99久久er| 九九热免费视频| 免费在线观看av网站| 成人视屏在线观看| 亚洲色爱综合| 人人爽网| 99丁香五月婷| 久久九九爽| 久久久久久久久18久久| 国产片天天爽夜夜爽| 北条麻妃九九九国产精品视频| 色综合av超碰| 欧美va| 91九色精品熟女内射| 色www99| 丁香六月婷月91婷月| 激情5月婷婷| 性av| 深爱女色婷婷丁香五月亚洲图区| 狠狠色大香蕉| 超级97碰碰| 日韩AAA| 久久婷婷五月天| 久99久视频精选| 婷婷五月天,影院| 碰碰女| 五月婷丁香久久综合| 婷婷五月天国产手机在线视频观看| 9热在线观看| 成人AV片播放| 九九机热| 久久九久久| 婷五月天在线草| 色色亚洲五月天| 六月丁香色色色| 五月亚洲| 丁香五月WWW| 天天肏天天爽夜夜爽| 婷婷激情五月| 六月伊人婷婷| 亚洲亚洲人成综合网络| 久婷婷五月激情| 99综合视频一体| 婷婷综合成人| 久久婷婷五月综合成人d啪| 婷婷激情五月综合| 丁香六月激情毛片| 婷婷丁香五月综合免费视频百花| 久久一伦| 丁香五月AV| 哇嘎成人久久| 超碰三级片| 五月丁香色婷婷色| 超碰免费成人| 亚洲精品视频在线| 国产精品美女| 色月视频| 午夜亚洲AV日韩无码| 狠狠狠狠免费| 综合久久婷婷99| 思思热久久婷婷五月天| 国产黄色大片| 99视频网址| 色噜噜狠狠色综合成人99| 久久99久久99精品免观看粉嫩| 2013AV天堂| 婷婷六月综合基地| 国产成人综合网| 五月天成人综合| 激情丁香婷婷五月天| 97高清国语自产拍| www,26uuu,c0m,色情| 色吊丝av中文字幕| 久久婷婷五月丁香网| 另类小说五月天| 涩五月婷婷| 婷婷激情五月天亚洲综合| 五月婷婷综合在线视频| 色婷婷69| 好好日激情五月天| 九月av在线| 91一起艹| 思思热在线视频99| 99精品久久久久| 天天插天天干| 激情综合五月婷婷六月丁香| 婷婷色导航| 中国丰满熟女A片免费观| 五月天婷婷无码视频| 色天使色婷婷| 91精品久久久久久久久久| 久久99热这里只有精品| 噜噜色五月| 大香蕉丁香五月| 超碰成人在线观看| 激情五月婷婷在线| 亚洲成人综合在线| 神马久久五月天| 五月婷丁香| 五月婷网站| 午夜成人天堂久久无码日韩久久| 女人被躁到高潮嗷嗷叫小| 久久538| 久久久er热| 在线91日韩| 久久HD| www.久热| 五月天激情婷婷小说| 久久婷婷啪啪视频| 热久91| 午夜大香蕉| 99这里有精品视频| 青青草日本亚洲| 91超级碰| 超碰国产av| 欧美综合激情| www.99色| 五月婷婷六月丁香| 天天弄天天操| 丁香五月婷婷激情中文| 五月婷高清视频| 91avse| 97久久超视频| 久在热99| 中文字幕一色哟哟哟哟| 激情99| 五月丁香六月色| 亚洲最大五月六月丁香婷婷| 色婷婷婷综合五月天| 在线观看的av| 六月丁香色色| 色五月婷婷自拍| 四色五月婷婷| 九月丁香婷婷网| 五月开心网| 中文AV在线播放| 五月激情五月婷婷五月天在线| 丁香五月天激情网址| 美国不卡视频| 一片AV片免费播放| 亚洲狠狠色丁香婷婷综合久久| 色五月五月天色婷婷色五月| 99er精品视频| 亚洲日韩成人三级av| 天天肏视频| 五月天亚洲综合网| 激情五月婷婷网| 欧美综合五月丁香六月婷| 思思视频这里是精品| 丁香六月啪啪啪| 婷婷丁香91| 69精品人妻不卡视频| 九九XX视频| 色九四色| 日韩五月婷婷久久| www.韩日视频| 97碰碰草| 综合五月丁香97| 久久亭亭电影| 五月激情综合婷婷| 婷婷五月激情综合啪啪| 2021日韩无码| 99热性色| 91色九| 亚洲区视频| 亚洲旡码| 人妻自慰在线| 99久久a线观| 五月丁香啪啪啪啪| 婷婷精品在线| 99只有这里是精品| 五月丁香婷婷AV| 久久爱婷婷| 99久在线观看| 欧美久热| 最近中文字幕大全免费版在线| 99爱精品| 97色综合视频| 婷婷五月丁香香蕉| 91碰| 综合在线丁香五月| 五月婷久久久久综合| 99热综合在线观看| 1769在线观看欧美国产| 婷婷综合亚洲| 91精品电影18T| 欧美性爱5月天天天看| 蜜乳中文字| WWW.婷婷五月天.COM| 日日夜夜婷婷| 男女av免费看| 丁香婷婷五月六月久久| 亚洲中文无码成人| 国产精品成人av在线观看春天| 黄页大全十八禁| 五月天网站免费欧美| 丁香六月激情| 95精品区一区二| 久久久精品99| 久久亚洲色导航| 丁香五月中文字幕久色| 99九九精品| 久久99国产综合精品免费| 96色婷婷| 99久久99视频只有精品| 狠狠色噜噜| 粉嫩av懂色av蜜臀av熟妇| 少妇搡BBBB搡BBB搡毛茸茸| 狠狠狠狠草草| 大香蕉九九| 色五月激情婷婷| 九九热欧美| 就爱日五月天| 丁香色六月| 激情五月天激情五月天| 激情开心五月天| 中文字幕无码成人电影| 婷婷伊人无码| 99这里有精品视频| 99九九这里有免费视频| j久久性爱视频| 久草五月丁香婷婷综合| 亚洲小视频免费播放| 色婷婷亚洲在线| 开心五月深爱五月| 欧美在线视频9| www.伊人天堂偷偷婷婷| 五月丁香激情四射| 婷婷日本色| 五月天亚洲最大成人| 99精品久久久久| 香蕉网婷婷| 色色狼人综合| 人人草人人看| 五月婷视频| 天天在线天天综合网色| 色婷婷免费观看| 亚洲无码激情| 丁香五月激情性色郤| 91操人| 五月丁香久人妻中文| 26uuu精品一区二区| 免费观看欧美成人AA片爱我多深| 色狠狠五月天| 综合激情在线视频| 国产精品美女| 色综合色综合色综合色综合| 97超碰9久热婷婷热| 亚洲 日韩色色| 色999亚洲人成色| 亚洲一区二区无遮挡A片| 亚洲天堂aaa| 蜜臀久久99精品久久久久久酒店| 婷婷久久免费看| 九九热精品视频| 丁香婷婷色五月| www.maotanji.com| 丁香五月婷婷av| 丁香五月婷婷日本| 久九九热| 欧美这里只有精品| 欧美色色日韩| 色婷婷婷婷五月天| 久久的爱大香蕉| 久热网在线视频| 五月天婷婷无码| 五月中旬婷婷丁香六| WWW嗯嗯啊啊啊啊| 中文aV网| 五月婷婷激情在线| 色情五月停停丁香| 9在线9在线婷婷在线国产| 激情九九这里只有精品| 狠狠爱婷婷五月天| 无码 色| 亚洲啪啪精品| 亚洲婷婷五月天激情| 操人视频91| 亚洲成人网站在线播放| 亚洲第一成人无码A片| 4399亚洲视频| 只有精品视频在线观看| 91超级碰| 人人人操97| 啪啪色激情五月天| 综激情网| 久久五月视频| 色婷婷8| 天天综合天综合| 久久综合播放| 亚洲色碰| 六月亚洲| 久久九九思思| 久久婷婷丁香| 婷婷五月天免费小说| 亚洲国产无线乱码在线观看| 99热这里只有精品50| 五月天婷婷涩涩| 大香蕉伊人爱在线| 激情四射五月天偷偷看婷婷| 亚洲无AV在线中文字幕| 亚洲激情精品| …亚洲黄色在线播放日韩、av中文a…| www.婷婷亚洲基地| 天天综合亚洲综合网天天αⅴ| 桃色五月婷婷| 免费亚洲婷婷五月| www.av视频xx999.com| 亚洲精品无人区| 久久激情网| 99色在线| 丁香五月成人自拍| 中美日韩成人在线| 国产色五月婷婷| 伊人网啪啪| 丰满老熟妇BBBBB搡BBB| 激情五月婷婷开心网| 婷婷综合五月| 丁香婷婷激情| 日韩aaaaa| 色宗合,宗合网| www.99免费视频| 99噜噜噜在线播放| 玖玖资源在线视频| 亚洲色欲欧美一区二区三区| 激情国产五月| 成人丁香| 丁香婷婷视频在线| 伊人在线婷婷草| 草榴视频网| 成人免费黄色短视频| 久久精品系列| 国产精品五月天婷婷| 亚洲高清在线| 久久hd| 激情婷婷五月| 五月天婷婷综合网| 欧美va亚洲va在线播放| 国产激情视频在线观看| 午夜福利8055| 国产精品人成A片一区二区| 久久伦乱| 性生活久久朋友人妻| www.粉嫩av.com| 冬月かえでAV无码播放| 97超碰,人人舔,人人操,人人摸| 久超超碰| 伊人在线视频| 日日射天天射| 婷丁香五月天| 日韩无码成人电影| 毛片新网地| 99九九热视频免费| 婷婷丁香熟女| 激情又色又爽又黄的A片| 在线观看av网站| 久久婷婷六月综合综合色| 婷婷五月永远18免费久久久| 久久婷婷五月综合97色一本| 成人在线网站| 丁香花成人区| 免费色婷婷| 国产内射婷婷| 伊人久久丁香狠狠婷婷综合香蕉| 女人天堂AV| 色99视频| 色婷视频| 91欧美| 91九色欧美| www,com,五月色色| 久久爱婷婷| 久热这里只有精品6| 天天日夜夜高潮| 亚洲成人色五月婷婷综合| 草综合网| 日本99久久| 日本色色图| 亚洲综合视频在线| 99热99色| 婷婷久久网| 激情综合婷婷五月| 狠狠干五月天婷婷网| 99er这里只有精品| 九九热这里精品| 色五月天天在线观看资源站| 丁香五月综合色婷婷| 午夜大香蕉| 天天综合色丁香| WWW·天天操·视频?| 九九精品片一| 成人欧美一区二区三区在线观看| 丁香五月天殴美激情| 久久草婷婷丁香网站| 天天久久综合| 五月天婷婷视频| 丁香五月人妻| 丁香五月久久| 91啪啪视频| 精品欧美性爱超级爽| 色亭亭影园| 玖玖婷婷视频| 超碰91在线| 天天天久久久| 五月丁香亚洲综合网| 五月天狠狠干| h在线看免费版在线看| 五月天色色婷婷| 色99在线观看| 色和综合网| 亚洲天堂制| 久久精品63| 欧美性二区| 99精品网站| 欧美日韩AAAA| 97干免费视频| 99色在线| 色吊操色妞| 激情九月婷婷| 六月婷婷色五月| 丁香五月婷婷视频| 色色婷婷五月| 亚洲无码影音| 色情五月婷| 丁香五月亚洲天堂| 色播激情| 久久视频婷婷| 久热这里只有国产| 狠狠干五月丁香综合网| 中文字幕精品在线观看| 亚洲成人免费电影| 国成人网| 狠狠色丁香| 操射国产日本| 五月婷婷啪啪啪| 性按摩玩人妻HD中文字幕| 婷婷狠狠狠爱| 日日操夜夜操狠狠操| 99热久草| 婷婷六月天| se.久久视频在线观看| 中文字幕在线免费观看视频| 操逼棍操逼| 久久久8| 九九99视频精品| 欧洲亚洲午夜| 午夜性做爰电影| 婷婷爱爱蜜臀天天操| 久久杏爱视频| 2017狠狠干| 婷婷五月天天| 亚洲VA欧美VA| 五月丁香六月婷婷激情网| 五月丁香综合啪啪| 国内一级精品| 五月丁香六月情亚洲| 97色色网| 婷婷丁香九月| 开心五月婷| 色优久久| 一本久道综合99| 色久五月天| 三级片AAA久久久AAA久久久AAA| 91成人看片| 欧美人妻一区二区| 成人午夜无码视频| 成人电影AV在线观看| 五月丁香少妇网| 亚洲色99| 婷婷五月天综合网| 一级性爱视频| 热99色| www.maotanji.com| 激情五月色播五月| 91久女| 九九99视频精品| 99视频在线精品免费观看2| 日本道久久91| 五月丁香青草综合啪啪| 性无码专区无码| 婷婷久久五月| 五月色色色| 碰超99| 色婷婷电影网| 美女xx不卡| 狠狠操狠狠干综合| 五月婷婷丁香日韩在线| 襙比视频| 色婷婷五月天| 婷婷色播六月无码| 久色视频| 九九人妻福利| 丁香五月天激情| 99精品在线观看| www夜夜| 亚洲最大在线| 五月天婷婷基地| 丁香五月婷婷啪啪| 丁香五月欧美成人| 久久五月丁香| 在线综合网| 婷婷色色网| 99这里只有精品视频| 九九五月天| 青草五月天| AAAA亚洲| 婷色五月| 五月天婷婷伊人| 亚洲精品一区中文字幕乱码| 六月丁香综合网| 激情五月天婷婷播播久久综合91| 丁香亚洲婷婷五月| 久99婷婷色综合| 思思国产99| 久久99免费视频| www.maotanji.com| 激情综合网五月丁香| 99热在线播放| 六月色色综合| 黄桃AV无码免费一区二区三区 | 国产亚洲AV人片在线| 99这里只有精| 97资源碰碰在线| av人人干| www.思思99热| 超碰人人插| 天天日夜夜| 天天搞夜夜爽夜夜爽| 婷婷五月天色色| 久久成人天| 天天综合色99| 99操视频| 我爱va亚洲va52| 丁香五月婷婷激情蜜桃| 午夜爱爱网站| 国产精品在线视频| 免费在线观看AV网站| 五月天婷婷激情小说电影| 97久人人| 亚洲国产精品SUV| 天天综合中文| 超级碰碰碰97免费| 思思热视频| 99热这里只有精品国产精品| 内射综合网| 日本99视频| 色 色 色综合com| 久久婷婷视频| av网址在线播放| www.久久久久久久| 伊人婷婷色激情丁香| www,色综合| 亚洲人妻av| 欧洲色| 五月天色色激情综合| 国产在线网址1| 激情综合网色播五月| 狠狠看狠狠| 91pornav在线| 色偷偷综合| 91精品久久久久、久五月天| 五月六月丁香婷婷在线观看| 91丁香色五月| 超碰免费人人| 97人妻人人| 久久婷婷网| 久狠日av| 操笔无码| 久久9RE热视频精品98| 欧美性生交A片免费看| 欧美精产国品一二三区| 婷婷五月激情丁香激情| 国产精品视频网| 欧美搡BBBBB摔BBBBB| 六月久久婷婷| 春色激情第四色| 色播五月丁香| 色婷婷AV在线| 五月天丁香色色| 大香蕉久操| 99热亚洲| 婷婷五月天在线观看第二页| a69在线视频| AV在线中文| 20253AV| 国产亚洲精品久久久久久郑州| 丁香 亚洲 久久| VA婷婷亚洲| 狠狠88综合久久久久噜噜噜| 久久婷婷综| 丁香9月婷婷| 色婷丁香91| 国产3p露脸普通话对白| 啊V视频在线观看| 婷婷五月天综合网| 五月丁香六月婷婷久久| 久久er+| 激情丁香五月婷| 丁香五月天啪啪| 伊人碰碰婷婷| 国产99久9在线| 99re在线免费视频| 91久久久久久久久久18| 婷婷六月天| 久久久18| 亚洲激情综合| 六月婷婷色综合| 91人人爽狠狠狠| 99热精品在线在线| 五月欧美丁香在线观看| 婷婷伊人网| 五月婷久久在线| 五月丁香六月花| 偷拍视频五月天| 天天日狠狠| 丁香五月婷婷成人综合| 五月色婷婷影视在线电影| 婷婷她六月天| 天天 青草 制服丝袜 在线| 啪啪色激情五月天| 亚洲精品视频在线播放| 九九99免费视频| 天天搞夜夜爽夜夜爽| 久久久久久99精品无码| 性爱七区| 久久伦乱| www.久久爱| 国产亚洲99久久精品| www.天天干| 五月天色综合| 色综合色色| 国产毛片精品一区二区色欲黄A片 欧美交换配乱吟粗大25P | 成人网站在线观看视频| 性爱综合网| 人妻熟妇国产精品| 天天爽天天爽天天爽天天爽天天爽| 丁香六月婷婷综合色| 免费国产VA国产免费| 亚洲激情高潮| 久久机热这里只有精品| 日本AAAAAAAAAAAAAA片| 天天爱天天吃狠天天透| 欧美三日本三级少妇三99| 九九色综合网| 五月婷丁香| se99视频| av高清无码| 五月婷婷狠狠久久| 久久与婷婷| 久久久999精品| 婷婷大美在线| 深夜激情网| 99热这里| 91一起操| 色综合99无码 | 九九成人精品| www,天天干| 在线观看欧美| 最近中文字幕大全免费版在线| 极品精品一区二区三区在线| 欧类av怡春院| 五月丁香亭亭AV女优| 九九久久五月天综合伊人| 五月天久久婷婷婷| 五月丁香六月欧美| 五月婷婷视频| 97在线精品| 久久久91精品| 亚洲av综合网| 去干网最新版本亚洲版| 色婷婷裸体色性在线| 超碰成人电影| 草草女人亚洲| 超碰99久久| 久久久久久久久久久久久久人妻视频| av人人操| 九九亚洲视频| 精品国产乱码久久久久久免费| 在线综合91| 色五月涩涩婷婷蜜桃| 九九这里都是精品| 婷婷五月天AV| 91人妻九色大屁股| 久久久网站| 操熟女成人网| 色五月激情五月| 丁香五月激情欧美| 九九av| 激情色视频| 操99| 婷婷久久伊人| 激情99。| 五月婷婷色影院| 好吊兆人妻| 日韩色色小视频| 五月天综合在线观看| 99自拍视频| 综合激情在线| 久久狠狠欧美| 播五月,色五月,开心五月播放器| 日日做A爰片久久毛片A片英语| 激情AV在线| 九月色婷婷综合| 激情综合久久| 97视频.干com| 九九视频在线观看| 久久婷婷五月天| 久久新地址| 可以免费观看的av| 国产成人精品一区二三区熟女在线| 中文字幕婷婷五月天| 婷婷综合欧美| 五月婷婷色五月| 香蕉婷婷五月| 婷婷色五月婷婷姐妹| 激情小说在线视频| 久久99草五月婷婷| 森林影视大全,最好看的2019年视频 | 婷婷精品免费久久| 亚洲图片 丁香婷婷| 久久五月婷综合网| 综合网亚洲| 99人人精品| 亚美欧色影院| 精品99*| 丁香5月啪啪| 女人天堂AV| 在线播放中文字幕| 日韩av在线免费观看| 久久人操-久草婷婷-成人AV| 色亚洲婷婷| 亚洲国产精品VA在线看黑人| 开心 五月 综合| 五月天丁香| 91超碰在线观看| 婷婷五月天激情综合| 色噜噜夜夜夜综合网| 日日干夜夜干| www.91AV.COM| 久久99热这里只有精品| 97操男人的天堂| 丁香五月Av| 国产精品A片在线| www激情五月天| 久久久.www| 激情亚洲网| 丁香五月婷婷影视先锋| 亚洲天堂aaa| 91丨九色丨国产在线| 色激情五月天|