99精品久久精品一区二区-亚洲熟妇无码?v在线播放-日本国产精品无码字幕在线观看-久久久亚洲永夜AV-亚洲一级无码一区二区一-免费国产成高清人在线视频-中文字幕乱码免费观看-国产毛片精品妇女久久久

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久久精品国产91性色TV| 91九色国产| 裸体做A爰片毛片A片免费| 丁香婷婷久久老熟女综合网| 99er热精品视频| 97操碰碰无码视频| 天天爽综合网| 99色在线观看免费| 色婷婷88| 1024你懂的欧美曰韩| 激情久久久| 婷婷色五月偷拍| 婷五月天丁香婷五月| 超碰99在线观看| 五月婷婷丁香社区| 高潮毛片遮挡费高一百度| 人碰人人人玩91| 夜夜 操无码| 狠狠色婷婷在线| 乱岳熟女50岁| 婷婷九月| 99综合一区| 97人人操人人爽| 波多野结衣不卡AV| 五月婷三级片| 成人亚洲精品久久久久| 国产精品VIDEOSSEX久久发布| 欧美色频| 九九热这里| VA国产在线综合网站| 极骚大香蕉伊人| 天堂网啪啪| 婷婷五月天亚洲丁香| 轮奸综合网| 亚洲有码在线视频| 五月丁香色| 99热最新地址在线| 狠狠综合色网| 久久狠婷婷| 丁香五月激情图片婷婷| 伊人九九68| 北京熟妇搡BBBB搡BBBB| 欧美性色A片免费免费观看的| 九九色99| 亭亭五月丁香五月天激情| 五月天亭亭俺也| 日本成人噜噜噜噜噜| 91日本在线观看| 七七色色综合| 婷婷六月激情| 啪啪色激情五月天| 六月丁香啪啪| 久久久五月天网站| 九九热啪啪| 久久精品夜色噜噜亚洲a∨| 在线观看国产高清视频免费网站| 99热这里只有精| 激情五月天啪啪| 激情五月天视频| 狠狠色综合网站久久久久| 丁香五月天精品| 日本精品。999| 天天做天天爱天天日| 久操干| 亚洲无码猫咪| 丁香婷婷色色| 开心六月婷| 天天色天天搡| 婷婷五月婷婷五月天| 激情av在线| 免费啪啪啪网站| 超级久久久| 九九色黄色| 五月婷三级片| 青青日韩| 99性视频| 久草婷婷网 | 亚洲成人免费在线| 丁香五月图片| 无月播播激情在线观看视频| 五月婷伊人| 色综久久久| jiujiu无码五区| 五月丁香六月婷婷免费| 婷婷成人五月天成人文学小说| 五月天啪啪| 免费看欧美成人A片无码| 五月婷婷人人人操| 亚洲亚洲人成综合网络| 激情碰碰碰| 婷婷九月在线| 99热费观看| 99ri国产| 五月婷婷婷婷婷| 影音先锋 91工厂| 天天添天天摸天天天天做| 九九热视频网站| 五月婷婷六月爱| 亚洲色模骚货| 久久人人妻| 国产91资源在线| 2022久久婷婷| xxxx五月| 色播色丁香五月| 韩国不卡AC视频| 五月婷婷综合影院| 天天日人人| 婷婷之六月丁香| 亚洲精品色| 婷婷色色五月天| 日本强伦片中文字幕免费看| 日本久久高清| 丁香五月电影| 嫩草AV久久伊人妇女超级A| 精品香蕉99久久久久网站| 国产操逼网站| www.伊人天堂偷偷婷婷| 成人av在线电影| 国产成人网址| 美女激情综合| 婷婷王月天影院| 色色丁香| 99国产精品久久久久久久久久久| 99色热| 日日操无码| 丁香九月婷| 日韩色色小视频| 色色色色色色色色色999| 五月天婷婷青青| 激情综合一| 五月天婷婷在线AN| 一二线视频 另类| 97热视频| 久久99看免费| 免费观看的AV| 欧美私人家庭影院| 五月丁婷香| www.henhengan| 久久久香| 91精产一区三区免费观看| 成人操呦av| 国产精品久久久海的味道| 99精品成人无码A片观看金桔| 久久性爱视频| 久久 无毛。| 婷婷国产综合| 亚洲成人免费电影| 婷婷五月激情的图片| 激情亚洲五月| 99国产精品久久久久久久久久久| 九九热在线观看6| 99热免| 久久综合五月天| 超碰色碰碰| 99热只有精品在线播放| 五月天婷婷基地| 丁香六月婷婷社区| 草综合14| 欧美成人精品A片免费一区99| yazhochengrenavwang| 五月天影院婷婷在线观看| 九九色人| 99热插| 五月婷色啪| 成人国产欧美大片一区| 六月丁香婷| 天天色天天日天天舔| 婷婷五月精品| 丁香五月婷婷激情中文| 大战熟女丰满人妻AV| 激情综合网址| 色播五月丁香| 97人人操| 久久婷婷六月综合| 五月天激情黄色小说在线观看| 色99色| 影音先锋男人女人| www夜夜操wwwcon| 亚洲日韩乱码一区二区三区四区| 噜噜噜噜在线| 久久色吧| 99热免费在线| 人人妖人人97| 五月婷婷狠狠干| 国产精品色情AAAAA片软件| 草操网| 色情五月综合婷婷| 79色色免费| 亚洲成人AV电影在线| 色五月开心五月激情五月| 日日干夜夜干| 久操b网| 色色五月天婷婷| www.minyis.com【JT】实力收量可预付TG@LXSPSW8 | 免费黄色视频网址| 丁香丁香激情网| 激情五月婷婷| 国产乱妇乱子伦| 欧美性猛交AAAA片黑人 | 精品成人在线观看| 99在线精品观看99| 激情五月婷婷色综合| 欧美私人家庭影院| aaa日韩| 亚洲国产精品二二三三区| 五月激情综合激情五月| www.九月婷婷丁香.com| 综合色五月| 婷婷美女精品视频| 婷婷五月丁香A∨| 色综合另类| 久婷婷婷| AⅤ网站在线看| 开心婷婷丁香五月| 久久婷婷的综合色丁香五月| 人人爱国产| 婷婷伊人中文字幕| 婷婷欠久少妇| 久久婷婷影院| 欧美日韩成人h| 天天干com| 欧洲精品爱爱| 久久久99精品免费观看| 天天爱天天做天天| 五月天婷婷自拍图片在线观看| 亚洲中字AV电影在线网站| 野战毛片三一3| 激情综合啪啪| 久久综合综合综合| 99久久久久| 色五月婷婷啪啪五月| 五月丁香偷拍| 欧洲MV日韩MV国产| 97碰碰视频在线观看免费| 亚洲综合色网站| 九九色情网五月天| 成熟妇人A片免费看网站| 99热99热不卡| 激情五月激情综合网一级丸片 | 久久杏爱视频| 婷婷色在线视频| 被强行糟蹋的女人A片| Www.狠狠| 婷丁香五月天| 婷婷五月色| 五月天激情中文字幕| 丁香婷婷午夜| 久久婷婷七月丁香| 欧美色频| 激情综合五月天| 五月丁香婷婷人体| 久久婷婷六月天| 激情五月天婷婷丁香| www.色五月| 婷婷欧美激情| 爱婷婷久久视频| 色情综合| 五月天婷婷狠狠| 亚洲V国产V欧美V久久久久久| 日日肏夜夜干| 国产色色网站网址| 婷婷99狠狠| 9 9 9色色| 亚洲乱码日产精品BD在线观看 | 日本啪啪网| 久热re视频在线观看网站| 亚洲av网站| 99热这里只有精品最新网址| 久久这里都是精品视频| 精品无码av丁香五月激情| 黄色91在线观看| 色.五月综合网| 思思久久精品| 97在线精品| 亚洲操操操| 久久久月丁香| 五月 丁香 欧美| 超碰激情网| 久碰综合| 99综合熟女| 狠狠婷婷综合| 激情性爱五月天网页| 婷婷五月色播| 五月天婷婷久久| 国产激情综合| 色五月综合网| 大香蕉九九| 婷婷丁香小说| 五月丁香激情综合网| 热99精品视频| 亚艹艹| 五月天婷婷青青草| 五月视频日本免费观看| 六月丁香基地| 六月丁香花婷婷| 色域五月丁香| www九月婷婷| 无码字幕中文| 色 五月 天 婷婷 丁香 九月| 五月天sesese| 色吊丝99| 婷婷五月天激情电影| 啪精品| 久久色大香蕉| 色婷婷亚洲综合天堂| 免费黄网不卡AV| 亚洲精品V天堂中文字幕| 亚洲精品字幕在线观看| 色婷婷六月| 欧美久久九九| 激情六月天| 天天操夜夜橾| XX久久| 六月婷婷啪啪| 婷婷五月天小说网| 风流少妇A片一区二区蜜桃 | 新97人人上人人| 日本欧美国产| 99热久只有| 色五月婷婷成人视频| 五月色婷婷影视在线电影| 婷婷色女| 色六月丁香婷婷狠狠干| 开心五月深爱五月丁香五月激情五月| 五月天啪啪啪| 中文字幕不卡+婷婷五月| 婷婷五月电影院| 天天操天天操天天操天天操天天操天天操天天操天天操天天操 | 五月天天天色| 五月停停色色丁香| 五月天激情小说| 免费看欧美成人A片无码| av一级棒av| 丁香花狠狠婷婷亚洲中文字幕| 99色在线视频观看| 天堂资源欧日浪女在线播放| 深夜婷婷五月丁香| 99在线小视频| 亭亭玉月丁香| 丝袜熟女一区二区三区| 丁香五月婷婷激情网| 综合激情啪啪| 99热99热| 亚洲六月婷婷| 日韩丁香涩| 亚洲AV无码影院| 97碰超级人人看| 色亚洲中文| www.思思99热| 五月激情六月综合| se婷97| 91人人操人人| 亚洲色情网站| 色久综合| 九九干视频| 丁香六月婷婷色XXXXX| 日本强伦片中文字幕免费看| www.久久爱.com| 天天搞夜夜叫| 播五月开心婷婷欧美综合| 狠狠综合网| 婷婷色五月激情| 婷婷激情97| 9久视频| 凹凸操Av| 69精品人人人人| 最新日韩久热免费视频看看| 五月丁激情| 五月丁香激情综合啪啪| 《亚洲操B久久免费在线观看,亚洲操B久久在线播放》在线播放 - 高清资源 - 97 | 亚洲成人另类| 伦99热| enecarbon-materials.comWu染请涟系Bao护@wip1688 | 五月视频日本免费观看| 超碰免费大香蕉| 国产暴力强伦轩1区二区小说| 五月婷婷色啪| 亚洲色亚洲精品| 日韩1区2区| 天堂在线婷婷| 米奇影视资源婷婷狠狠色激情欧美五月丁香| 天天做天天爱天天爽| 久久久这里有精品| 日本久久超碰| 五月天综合在线观看| www.色五月| 97婷婷在线视频| www婷婷色情网| 超碰chaompinm| 伊人大香久久| 日日操,日日爽| 97碰碰视频在线观看| 色99久草在线| 色欲资源网| 久久国产色| 色婷婷狠狠久久YY| 99热.com| bukadeavzaixian| 亭亭色天香| 99热超碰| 久久久人妻久久久| 九九久久综合| 久久ri精品视频| 狠狠搞综合色| 无码人妻少妇色欲AV一区二区| www.色色五月天.com| 日日综合网| 天天日天天肏天天奸| 国庆精品久久| 婷婷久久综合| 六月婷婷六月天天在线免费| 欧美99热| 五月天婷综合网站| 91热在线| 婷婷丁香在线| 激情六月丁| 丁香婷婷老熟女综合网| 日日撸日日操| 青青久久91| 六月五月婷婷| 五月天堂六月丁香亚州中文字幕久久| 亚洲第一精品网站| 五月婷婷九九久久| 91九色在线视频| 欧美97超碰| 国产在线另类五月婷婷| 草了bav视频在线观看| 色噜噜狠狠色综合网| 99色在线观看视频| 婷婷天天色| 综合久久影院| 丁香五月偷拍| 激情五月丁香在线观看直播| 欧美日韩成人h| 97色色色视屏| 一二线视频 另类| 五月色丁香激情| 大香伊人久色| 激情五月天小说|五月天开心激情网|亚洲精品国产自在现线|黄色五月天 | 五月婷婷色播| 五月天婷婷色色| 久久人人九| 婷婷丁香五月综合免费视频百花| 久99热在线观看| 99久久www| 97九色| 亚洲99综合| 色色色色综合| 五月丁香香蕉| 日本婷婷五月天| 欧美视频五区| 国产人妻777人伦精品HD| 天天舔天天| 国产欧美精品AAAAAA片| 亚洲精品久久久久久久久久吃药| 超碰伊人碰婷婷五月| 天天色综合图片| 大伊香蕉玖玖爱| 色五月婷婷基地| 亚洲色色在线| 色综啪啪| 婷香五月激情视频| 99热这里只有精品最新地址获取| 五月丁香久| 亚洲乱码日产精品BD| 在线sebiav精品视频| www.亚洲激情| 91人妻人人做人碰人人爽九色| 婷婷午夜| 五月天综合视频| 99热国内精品| 爱iii做iiii日| 啪啪黄页网| 色色五月天网站| 国产XXXX搡XXXXX搡麻豆| 激情深爱五月| 六月婷婷无码| 久热伊人9| 丁香婷婷久久 | 五月天久久激情| 丁香五月手机在线| 五月天五月婷五月激情网| 丁香五月婷婷Av| 欧美人与性动交CCOO| 五月花免费视频| 婷婷五月小说色综合| 免费一区二区三区| 欧美婷婷日本| 黄色AAAAA| 亚洲va日| 久久99久久99精品免观看粉嫩| 久久精品国产一区二区三区四区 | 怡红院视频| 99精品22| Av性爱网站| 色一情一乱一乱一区9| 五月天婷婷久久| 天天干狠狠| 十月丁香婷婷| 久久人视频| 久久九九免费视频| 丁香五月婷婷五月天| 欧洲日韩一区二区三区| 激情综合5| 综合五月丁香97| 成人做爰黄A片免费看直播室男男| 五月天激情四射网站| 天天射影视综合网| 日本五月婷婷久久久六月丁香| 97碰碰在线观看视频| 欧美A级成人婬片免费看理论| 性爱综合网| 婷婷亚洲五月| 26uuu另类| 这里只有精品99视频| 9l视频自拍9l九色9l成人| 99精品无码| 99秘 在线| 99色综合网| 9人人操人人看| 亚洲精品九九| 九九九干精品| 99精品热| 99视频这里有精品| 四色99久久| 五月婷婷中文字幕| 丁香婷婷十月| 婷婷五月天亚洲精品| VA日本视频| 婷婷视频网| 9热精品| 婷婷五月天大香蕉| 日韩有码久久| 成人AV网站在线| www.久操| 久cao香蕉影院| 免费看欧美成人A片无码| 超碰人人色| 婷婷五月综合久久中文字幕| 婷婷欧美综合| 日夜操B| 成人在线网| 爆乳熟妇一区二区三区爆乳| 激情丁香五月天| 五月婷婷免费在线观看视频| 美女五月天| 亚洲狠狠干| 色色色色网| 五月婷激情| 日本色五月婷婷| 丁香五月婷婷五月| 99人碰碰碰| 五月丁香婷婷久久| 婷婷五月天开心网| 激情五月天网| 婷婷五月色播天| 色婷婷狠狠禁久久| 丁香视频| 久九色| 另类在线| 五月丁香啪啪啪啪| 99思思| 婷婷五月激情中文字幕| 日韩AV片| 久久激情五月婷婷| 天天日天天舔| 五月婷婷丁香日韩在线| 亚洲乱啪| 大香蕉久操| 婷婷丁香色五月天久久88| 深爱激情AV| 人妻精品久久久久久久| 激情五月婷黄版| 色五月综合| 成人日韩欧美| 久久久久视剧HD| 欧美超级视频97| 99色热| 五月婷婷在线网站| www.天天干| 亭亭五月丁香五月天激情| 五月婷丁香| 天天色综合网吨吧| 日本WWW九九九| 99re8在这里只有精品| 性一交一乱一交A片久| 色天使色综合| 99久久婷婷国产综合| 99热九九这里只有精品10| 五月天激情啪啪| 99久久99久久| 婷婷D区| 99日精品视频| 亚洲婷婷婷| 99久在线精品99re5热视频| 中文字幕精品在线观看| 日本超碰在线| 99re免费精品视频| 久久色午夜在线导航| 人与禽A片啪啪| 亚洲成人免费电影| 超碰精品在线| 五月天婷婷激情六月久久 | 激情文学久久| 国产免费性爱| 国产成人AV在线播放| 五月亭亭直播| 1囯产午夜仑鲁鲁| 26uuu视频欧美| 天天狠狠干| 激情综合网五月激情| 精品成人在线| 五月激情丁香五月| 久久久精品人妻| 久草热8精品视频在线观看| 第五婷婷伊人丁香| 天天拍久久| 大香蕉手机视频| 日本wwww在线| 五月婷色| 亚洲成人网站在线播放| 五月婷三级片| WWW、日本色丁香co m| www婷婷| 久久精品国产精品| 久久婷婷视频| 五月丁香久久| av操B网站| 思思视频这里是精品| 在线成人视频免费| 色婷婷小视频| 婷婷色色播五月天| 99福利导航| 97午夜一区二区| 激情综合女人网五月播播| 久草狼人| 91精品丝袜久久久久久久久粉嫩| 狠狠干青青草| 激情丁香五月婷婷| 色婷婷电影| www.91AV.COM| 综合五月天完整| 日日做A爰片久久毛片A片英语| 欧美大香蕉视频| 日日夜夜狠狠操| 五月久久综合| 99久久成人| 天天操夜夜操| 日本本土色网第一区| 伊人干综合| 97干综合网| 激情图片五月天| 5Www色5夜| 日本九九热| 久久视频在线视频| 插插插色综合网| 武则天精品久久| 狼人婷婷综合| 色婷婷激情| 久久精品99久久久久久| 99色在线观看视频| 日本色图综合| 99国产精品久久久久久久久久久| www激情网站| 亭亭玉月丁香| 色欲影香| 亚洲愉拍99热成人精品| 狠狠操综合| 一起草性爱不卡视频| 久久XX| 久久免片| 超碰色综合| 五月婷婷综合激情网| 九九精品热| 97色干| 狠狠色官网| www久久久久久久久久久| www.激情.com.| 五月综合久久| 婷婷激情蜜桃玖玖丁香| 欧美在线ee日韩| 99亚洲日韩| 综合五月丁香六月婷婷| 狠狠色噜噜狠狠狠狠综合| 午夜成人AV在线| 日本丁香五月| 激情五月亚洲综合网| 久久这里只| 久久婷婷五月综合色和| 国产亚洲色婷婷久久99精品91| 99热日| 日日夜夜天天综合| 亚洲成人色五月婷婷综合| 99精品偷自拍| 色噜噜狠狠插综合| 婷婷射丁香| 九九色综合| 亚洲色vA| 99丁香五月婷| 日本一级一级一级一级| 婷婷五月天AV激情| 日本在线观看aaa 99| 天天日 天天草| 色噜噜综合网| 五月婷婷基地| 婷婷五月视屏| 成人看片网站| 99久久国产综合精品五月天喷水\| 亚洲色优| 丁香无五月网| www.9色色色| 粉嫩av蜜桃av蜜臀av| 9999热精品在线免费播放| 婷婷五月天亚洲综合网| 亚洲AV人人操| anquye五月| 人伦30P| 性做爰A片免费视频A片直播| 久热亚洲| 亚洲射激情| 激情九月天天天天婷婷| 中文毛片无遮挡高潮免费| 亚洲色优| 激情综合网,婷婷| 久久婷婷亚洲无码一起| 亚洲无AV在线中文字幕| 久色激情| 少妇人妻凹凸视频| 97自拍视频在线| 中文不卡av| 少妇激情五月天| 久久免费婷婷视频| 97亚洲色 torrent magnet| 欧在线一区| 99热精品在线观看| 开心激情婷婷| 天天成人丁香美女AV| 婷婷亚洲天堂| 9热在线视频| 99精品偷自拍| 色婷婷欧美| 五月天婷婷无码视频| 五月天婷五月天综合网小说首页-五月天激激婷婷大综合,婷婷亚洲综合五月天小说 | 91丨九色丨熟女|新版| 蜜乳A√| 五月丁香久久网| 伊人喵咪a V| 天天做天天爱天天高潮| 五月 激情视频| 五月伊人综合| 97碰| 综合网狠狠| 激情五月婷婷视频| 91久久久久久| 五月天丁香网| 五月婷婷婷| 香蕉久日夜| 五月丁香影院| 婷婷五月天开心网| 久久综合首页| 久久六月综合| 天天操夜夜爽| 思思久久96热在精品国产,| 激情综合网丁香| 香蕉狠狠爱视频| 色色九九五月天 | 91九色熟女| 噜噜色婷婷| 99精品爱| 综合五月天天天天天五月| 这里只有精品日韩| 99在线观看| 色久女| 色五月婷婷综合在线| 婷婷伊人五月丁香天堂网| 任你爽在线视频| av操逼网| W色综合| 超碰婷婷色| 国产毛片精品一区二区色欲黄A片| 夜夜夜夜夜操| 五月天成人小说| AV大香蕉| 狠狠草在线观看| 操碰91| 久久久久9999| 色色丁香| 亚洲激情综合| 91久热| 亚洲精品亚洲人成人网| 五月天伊人| 99爱在线视频| 97色碰| 99啪啪| 白人荫道BBWBBB大荫道| 国产伦亲子伦亲子视频观看| 天天射影院| 99自拍视频| 日本不卡高字幕在线2019| 精品夜夜澡人妻无码AV| 亚洲激情婷婷| 开心五月深爱五月| 610018岁成人视频| 黄色高清无码| 超碰色天堂| 日本女人久久| 97干在线| 欧美99热| 五月天激情.com| 婷婷五月天电影区小说区| 天天草天天摸| 婷婷综合精品| a久久| 九八Av| 成人va在线| 99九九热视频| 丁香五月性爱| 五月社区婷婷激情| 六月婷婷在线| 亚洲五月婷| 欧美99热| 噼里啪啦完整版中文在线观看 | 秋霞少妇毛片| 99热亚洲| 婷婷综合五月激情| 5月婷婷五月天| 五月天婷婷色色网| 色五月激情五月| 国产精产国品一二三在观看| 久久五月天丁香花| 五月丁香婷婷基地| 色婷婷综合中心| www五月天com| 国产精品成人在线| 欧美性生交xXxX久久久| www.色情五月天.com| 狠狠爱综合| 激情影院免费视频婷婷五月天| 草逼大片| 五月天综合视频| 99热思思| 《丁香激情综合久久伊人久久》影视在线观看 -高清预告手机免费播放 -三妹影院 | 91久久精品视频| 成人在线精品| 美女主播野战视步页| 色婷婷丁香五月天| 中文字幕AV在线播放| 麻豆AV一区二区三区| 综合玖玖偷拍| site:jszngf.com| 天天日天天干天天爽| 色丁香五月| 丁香五月天日韩无码| 久久久激情视频| 色丁香婷婷美女视频网站| 五月丁香自拍| 欧美成人AAA片一区国产精品| 狠狠色丁香久久婷婷综合五月| 性无码专区无码| 99久久天堂婷婷| 亚洲国产婷婷色五月| 日日夜夜小色哥| 午夜五月天| 亚洲成人AV一区在线观看| 99色热| 五月丁香黄色视频| 五月婷婷综合激情| 久久综合首页| 五月天婷a| 五月天激情丁香| 丁香天堂夜| 秋霞网在线观看理论91| 久操人妻| 久啪欧美| 久99久热只有精品国产99| 天天操无码| 91猫咪国产在线播放| 思思视频这里是精品| 色香久久| 婷婷五月综合基地| 丁香五月色播中文在线播放| 人妻久热| 天花AV无码| 五月天全国最大成人网| 99色免费观看全部| 综合久久久婷| 丁香5月婷婷| av中文在线| 丁香色色网| 欧美日本另类| 玖玖91| 色综合色欲综合天天免费| 五月丁香成人| 婷婷狠狠综合网入口| WWW色综合| 色99视频| 91九色中文字幕女在线观看| 色婷婷色五月天| 中文字幕成人网站| 99久久a线观| 99啪啪| 日本一级一片免费视频| 99热久| 亚洲成人精品三区| 久久婷婷五月天激情| 97色在线| 五月丁香网av| 另类小说色婷婷| 综合网色| 深爱激情六月天| 九九综合伊人| AV在线免费播放| 九九美女视频| 五月草视频| 碰人人97| 六月婷婷九月丁香亚洲综合| 狠狠爱深色婷婷综合| 色婷丨日丨天丨综合久久| www.久久久久| 玖玖资源站国产| 五月婷婷av| 婷婷五月色| 激情五月天婷婷久久久久久久久久久| 天天干天天干天天| 97色色综合| 夜色综合网| 黑人无码一区| 9l视频自拍9l视频自拍九色学生| www.99热在线| 五月天婷婷影院| 激情人妻综合| 五月丁香六月婷婷色日| 91久久色| 99操视频| 五月花综合网| 强壮的公次次弄得我高潮A片日本 | 十月丁香婷婷| 国产毛片精品一区二区色欲黄A片| 婷婷五月天日逼| 欧美情色电影一区二区| 色播婷婷五月天| 色五月开心久久网| 五月丁香成人网| 亚洲婷婷91丁香| 久久机热/这里只有精品| 3pAV| 丁香婷婷五月份| 狠狠狠夜夜夜| 涩丁香91| 激情深爱五月天| 色九月婷婷综合| 久久人妻视频| 天天撸夜夜爽| 热婷婷在线视频| 日韩在线观看亚洲| av九九| 熟妇人妻中文字幕无码老熟妇| 五月婷婷丁香啪啪| 免费超碰在线观看| 亚州性爱99| 五月天婷婷情色| 青青草五月天| 天天插天天干天天舔| 丁香天堂夜| 色五月激情网| 五月婷婷婷婷婷婷艺术| 日本色色网站| 免费视频WWW在线观看网站| 人人摸人人搞| av婷婷丁香 六月| 婷婷五月丁香性爱| 99操99| 色婷婷丁香五月综合| 国产成人AV在线| 久热re视频在线观看网站| 久久婷婷色色| 五月婷婷在线观看| 97中文在线| 九九99九九精品视频| 久热伊人| 婷婷黄色五月天在线视频| 99色免费在线观看| 99热这里只有精品5| 综合五月激情网| 97资源欧美日韩大香蕉超碰一区| 这里只有精彩视频| 岛国AV网站| 婷婷五月播| 日韩精品在线观看9| 三级黄网站| 人妻精品久久久久久| 色色婷婷丁香| 开心五月婷婷在线视频免费观看| www.9797国产| 嫩草AV久久伊人妇女超级A| 99热精品无码| 丁香5月啪啪| 婷婷欧美综合| 丁香99| 99热思思| 66色在线日韩| 狠狠操天天日| 色V狠狠的干| 开心婷婷五月综合| 丁香五月天电影| 亚洲色网址| 777精品成人a v久久| 女同激情久久av久久| 婷婷色综合网日韩国产| 青青草五月天| 丁香五月天社区| 五月丁香色婷| 亚洲婷婷五月天在线激情综合网| 九九色婷婷五月天| 亚洲激情网| 玖玖热视频| 婷婷成人五月天一区| 婷婷久久精品| 丁香五月激情五月色综合| 丁香六月啪啪| 能看的av| 丁香五月亚洲综合| 99久久久国产大片| 超碰2021| 粉嫩AV久久一区二区三区| 26UUU欧美| 99国产精品久久久久久久久久久| 色性日本| 五月婷婷亚洲综合网| 91操片| 碰碰碰97国产| 中文字幕欧美日韩VA免费视频| 婷婷五月天黄色| 99精品视频网| 婷婷五月美女直播| 狠狠色狠狠干| 啪啪综合网| www.91.com黄| 天堂久久性| 极品少妇婷婷五月| 日日夜夜亚洲一区| 精品一二三区久久AAA片| 久久九区| 色婷婷19| 婷婷黄色| 九九碰九九爱97超碰| 色色五月婷婷| 天天操天天操天天操天天操天天操天天操天天操天天操天天操 | 色婷婷视频| 丁香五月色情| 五月丁香| 五月六月丁香激情视频| 激情婷婷内射| 丁香五月视频在线观看| 日日婷婷不卡| 淫荡工a| 九九亚洲视频| 婷婷五月综合网| 97操碰在线视频| 丁香五月婷婷色情综合| 久久视频婷婷视频| 啪啪啪大香蕉| 色综合久久久久| 无码人妻丰满熟妇奶水区码| 五月丁香本色在线观看| 久久婷婷五月综合网| 97久久超级| 成人中文字幕在线| 综合婷婷| 丁香六月av| 天天影视色综合网| 夜夜干夜夜操| 久久婷婷综合基地| 99热8| 免费看成人AA片无码视频吃奶| 欧美综合激情| 亚洲成人无码片| 九九热re99re6在线精品| 色婷五月| 丁香六月激情综合网| 色色综合视频| 女人被男人吃奶到高潮| 色色五月丁香| 亚洲国产精品VA在线看黑人 | 激情五月天免费视频| 激情小说婷婷五月| 精品久久久999| 狠狠狠狠狠| 91九色超碰| 欧美人久久| 99人这里只有精品| 天天操夜夜橾| 成人在线视频网| 人与禽A片啪啪| 久久女人九九| 欧美色色色| 久久机只有这里精品| 丁香五月中文字幕色播| 五月丁香综合激情| 色逼综合网| 99精品一二三四视频| 婷婷欧美色| 久久成人人妻| 91操人| 一本久久婷婷| 曰曰久久| 午夜婷婷五月天在线| 超碰在线观看9| 99国产精品白浆在线观看免费| 777久久久| 五月丁香综合网色欲| 精品成人a v无码内射| 人妻中文在线| 视频一区二区在线| 亚洲精品无码久久| 婷婷五月天成人综合网| 五月色婷| 雪千夏麻豆| 婷婷丁香在线| 无月播播激情在线观看视频| 99热这里只有精品16| 亚洲人成播放网站| 快乐激情五月色婷婷| 久久99热久久99精品| 99久久极情精品一区| 九九九AAA热视频| 欧美狠狠一在草| 五月婷婷在线视频| 免费观看全黄做爰的视频| 91色色色18| 色天天综合| 五月天另类激情在线| 婷婷性爱视频在线| 婷婷开心青青草| 色婷精品91| 九九Y精品热播| 久久综合热17c| 中文资源在线a | 婷婷五月丁香av网站| 色色网站| www久久久久久久久久久| 婷婷五月天影院| 五月丁香六月在线| 色五月激情五月| 99热九九这里只有精品| 五月婷婷综合丁香视频| 俺也去五月婷婷丁| 婷婷99| 色婷婷先锋| 精品无码片| 色五月丁香婷婷综合| 婷婷五月天久久久| 嫩草视频观看| 亚洲第79页| 婷婷五月天国产传媒| 亚洲视99| www久| 五月丁香激情怕怕| 日本操B视频| 欧美成人猛片AAAAAAA| 六月丁香视频网站| 日本久久综合| www91在线| 激情五月天在线视频| 六月婷综合| 成人婷婷深爱综合网| 99无码精品| 色综合色| 97久久人人操| 婷婷内射视频在线| 综合图片色色| 亚洲AV永久无码影院黑人 | 五月天伊人av| 狠狠插狠狠操| 狼人久草| 久久视频婷婷视频| 性色婷婷| WWW99热| 噜噜操操| 亚洲六月色婷婷| 婷婷丁香五月天影院| 天天做天天爽| 99免费在线视频| 五月天婷婷视频小说| 91 九色 入口| 亚洲国产精品VA在线看黑人| 9在线9在线婷婷在线国产| 青草激情综合| 91色欲综合| 久久久久丁香婷婷五月天| wuyuedingxiang| 色女伊人| 婷婷久久天堂网| 丁香色婷婷五月天| 日韩美女在线视频19| 九九这里只有精品| AV无码免费| 五月婷婷色综图片| 色5月婷婷| 深爱激情网噜噜色| 日韩黄色中文字幕| 99热这里有精品24| 婷婷婷婷婷婷婷婷婷婷丁香| 亭亭色天香| 五月婷婷av在线| 5月婷婷五月天| 日韩美一级毛卡片| 亚洲五月婷婷| 五月丁香婷婷综合久久| 九九99在线免费在线观看视频| 色婷婷久久| 天天做天天爱天天高潮| 夜夜天天天天天干天天爽| 狠狠干最新地址| 狠狠狠夜夜夜| 超碰97免费在线| 亚洲综合色婷婷| 玖玖伦理电影| 五月天大香蕉av| 丁香五月天激情免费在线观看AV777| 久久久A级视频| 日本三级韩三级99久久| 亚洲丁香婷婷五月天综合色| 成人午夜视频精品一区| 五月亭亭综合五码| 亚洲AV无码成人精品电影| 琪琪色五月天| 他改变了拜占庭| 色色欧美色色| 久久机热/这里只有精品| 天堂久久婷婷| 激情99| 五月丁香婷婷啪啪综合网| 婷婷五月天丁香久久| 大香蕉久久久久| 99热国产这里只有| 91狼友视频在线观看| 久久精品系列| 五月天激情国产综合婷婷婷就去爱| 怡红院AV亚洲一区二区三区H| 日日夜夜小色哥| 啪啪 综合网| 色五月激情网| 激情综合激情五月一起草| 色色爽爽天天| 欧美性生交XXXXX无码小说| 开心婷婷丁香五月| 热的国产99热| 九九色网| 九九伊人网| 99热精品一| 天天噜日日噜综合无码| 99精品偷自拍| 日日干日日| 丁香六月激情综合网| 亚洲爱婷婷| 婷婷啪啪| 夜夜撸夜夜骑| 天天拍夜夜撸| 久99精品视频| 日本色婷婷| 色婷婷小说网| 婷婷九月激情| 色激情五月| 亚洲综合网在线|