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
返回資訊列表
乱码操操| 99丁香五月婷| 屁股翘好撅高迎合跪趴| 婷婷在线视频| 久色激情| 天天搞天天爽| 五月花综合视频| 99综合视频一体| 婷婷中文综合网| 这里只有精品1| 九九热视频免费| 五月婷婷色影院| 黄色国久久| 超碰在线人人| 日日夜夜狠狠| 婷婷五月激情视频在线| 99热色在线精品| 丁香无月在线观看| 大香蕉五月丁香| 色欲久久99精品久久久久久| 婷婷五月激情黄色| 综合网五月天123| www.99久久久| 亚洲天99| 欧美在线97| 级人人91| 日日夜夜九九| WWW.五月com| 国外亚洲成AV人片在线观看| 九九成人| 午夜69成人做爰视频| 丁香五月激情网| 丁香五月婷婷欧美成人色图| 亚洲女婷婷五月基地综合久久久| 我要色综合五月婷婷| 国产ava| 九九九AAA热视频| 国外亚洲成AV人片在线观看| 欧美性生交A片免费看| 另类激情中文| 丁香五月婷婷色| 97色色色色色| 99国产精品白浆在线观看免费| 五月丁香啪啪综合| 日韩操人| 久久久久久久久久8888| 四LLL少妇BBBB槡BBBB| 高清无码入口| 98国产精品综合一区二区三区| 99久久99久久综合| 午夜精品人妻无码一区二区三区| 婷婷99视频在线| 人人操AV| 日本婷婷激情四射中文字幕在线观看| 久久婷婷一级片| 人操综合| 日本99视频精品免费播放| .comwww在线观看免费操| 色婷青青| 超碰人人99| 亚洲热久久| 婷婷六月情| 综合色色色色色色| 99re视频在线播放| 97五月天| 日日夜夜亚洲一区| 激情六月丁香| 亚洲色激婷| 婷婷五月天激情综合| 久久久er热| 夜夜躁狠狠| 99高级会所久久| 五月婷婷开心爱| 亚洲AAAA网| 激情九九这里只有精品| 日本高清久| 99久久激情视频| 99无码| 狠狠色婷婷7777久| 色婷婷狠狠久久综合五月| 97超级啪啪在线观看| 色色网91| 日韩免费乱轮网站| 综合五月丁香六月婷婷| 天天综合在线网| 91丨九色丨国产打屁股| 日韩五月婷婷| 五月天激情综合首页| 狠狠CAO日日穞夜夜穞AV| 中文字幕乱码亚洲精品一区| 色 五月 天 婷婷 丁香 九月| 91人妻人人操人人爽| 中文字幕成人| 99热这里只有免费精品| 人妻内射视频| 亚洲色图啪啪| 男人天堂亚洲综合| 婷婷五月丁香91| 色色色图| 天天综合网~91| 色五月天丁香| 日本色狠狠| 丁香大香蕉| 欧美日韩91| 九九成人电影婷婷| 99久久综合网| 婷婷五月天激情基地| 丁香五月婷婷综合精品素人| 免费黄网不卡AV| 亚州综合色| 久久久思思热| 日本五月天网站| 香蕉久久国产AV一区二区| 少妇熟女视频一区二区三区| 欧美日韩成人一区二区| 思思久日精品视频| 疯狂做受XXXX高潮A片| 五月色婷婷夜色| 玖玖国产视频一区| 91九色国产| 久久成人综合五月天| 五月天亚洲综合网| 665566 无码| 成人在线网址| 日日干日日| 少妇真实被内射视频三四区| 一级黄色影片| 五月婷婷深深爱| 亚洲亚洲人成综合网络| 99在线精品观看99| 狼人婷婷综合| 91久久九色| 丁香综合伊人| 六月丁丁香| 91超级碰人人操| 凹凸探花电影| 超碰人人在线| 99,色| 丁香五月天在线| 99只有精品| 色婷婷影音| 五月天亚洲最大成人| 色五月色图| 五月激情四射网站| www 五月天 com| 久久久99久久| 中文AV在线播放| 婷婷丁香人妻天天| 色吊丝99| 夜夜干夜夜操| 特黄三级又爽又粗又大| 四色AVwww| 国产又爽又猛又粗的视频A片| 久热中文字幕| 99黄色性生活| 色八月婷婷| 99热综合网| 精品九九婷婷| 婷婷爱五月天| 五月丁香久久久久| 色情综合| 六月丁香婷婷色狠狠久久| 色色五月婷婷久久| 五月丁香激情四射综合| 色婷婷影院| 美女激情综合| 天天狠狠夜夜狠狠2023| 国产偷人爽久久久久久老妇APP| 五月婷婷综合激情| 五月天激情婷婷| 五月 成人 婷婷| 亚洲色五月| 99热日本精品| 五月激情网站| 五月丁香六月婷婷亚洲天堂网站| 婷婷丁香五月天激情| 91综合国免费久入| 亚洲激情久久| www.狠狠干| 亚洲精品99| 亚洲综合九九| 激情综合五月婷婷| 久久这里99| 免费视频在线观看的网站| 久久这里面只有精品视频| www色五月| 激情五月天视频| 99日本精品视频热| 天天日天天干天天爱| 色婷婷激情| 激情五月天黄色小说| 99热97| 丁香六月婷婷缴情欧美| 99年操人人爽| 日本va欧美va国产激情| 97久久久久| 亚洲五月花| 亚洲艹网| 操逼综合激情网| 五月六月婷| 大香蕉久久草| 97超碰婷婷五月天| 久久小视频| 99操久久| 六月五月天婷婷涩播在线| 人妻VideOssS人妻| 久久婷五月婷| 久久婷婷青青草| 91碰碰碰久久久久| 99热这里精品| 久久婷婷五月综合啪| 婷婷六月天| 99热99极品观看| 99视频色在线观看| 婷婷WWW久久| 狠狠色丁香婷婷久久综合| 色五月首页| 六月丁香网| 久久er99| 激情美女五月天| 久久五月婷综合| 精品无吗va视频免费观看| 91超碰在线观看| av大香蕉| 成人版视频在线观看| 婷婷六月丁香激情| 另类视屏| 1024亚洲无码| 丁香五月Av| 五月丁香婷庭在线| 在线观看五月婷婷网| 91碰碰视频在线观看| 日韩淑女人妻luan伦激情精品一区二| 天干干夜夜操| 久操大香蕉| 婷婷五月天天| 五月天婷婷久久| 丁香五月婷婷手机| 日韩一66精品| 六月丁香av| 操B视频在线播放| 天天插天天射| 丁香婷婷午夜| 99ER热精品视频| 草综合14| 婷婷五月天首页| 色婷婷久久久| 91一道本| 琪琪狠狠干| 五月天色影院| 天天做天天爱天天高潮| 可以观看的AV| 亚洲综合狠狠艹| 六月丁香婷婷视频综合在线观看| 任你擦免费视频| 欧洲MV日韩MV国产| 久久小视频| 丁香久久综合| 婷婷爱五月| 亚洲行行色色| 成人小说 五月天 婷婷| 丁香六月啪| 久久资源综合| 日本成人内射| 亚洲无码影音| 五月天福利影院导航| 九九久久精品| 伊人狠狠丁香婷婷综合尤物| 婷婷亚洲五月| 久久人妻久久| 亚洲人成人五月天| 色婷婷亚洲在线| 五月花综合| 五月婷婷婷综合网| 无码动漫av| 色婷婷狠狠久久综合五月| 香蕉AV福利精品导航| 激情五月综合网最新| 99这里都是精品6| 日日射天天射| 成人狠狠成人狠狠成人狠狠成人狠狠| 插插干干干色| 五月综合六月丁| 99免费成人网| 狠狠88综合久久久久噜噜噜| 在线区区区| 99碰碰| 人伦30P| 97碰人人操| 肏日网在线看| 超碰高清在线| 另类伊人婷婷| av在线资源| 碰碰女| 五月天天综合| 99久久9| 91操熟女| 99久久99热| 婷婷五月天中文字幕.| 色婷五月天| 超碰97人人操| 婷婷久久丁香| 五月天色五月| 亚洲中文字幕AV在线| 国产精品扒开腿做爽爽爽A片唱戏 亚洲爆乳无码精品AAA片蜜桃 | 五月天婷婷丁香| 色啪影院| 少妇人妻偷人精品无码视频新浪| 中文字幕乱码亚洲精品一区| 丁香五月婷婷国产在线| 久久9999| 99视频超级精品| www.婷婷网| 在线五月色播| 中国激情网| 五月色丁香视频精品| 巴基斯坦粉嫩无码视频| 色五月av| 色婷婷电影网| 五月丁小婷婷激情四射| 69久热| 亚洲AV无码一区二| 五月六月播婷婷| 天天狠天天狠| 99热中国| 120分钟婬片免费看| 激情综合五| 一本道在线电影| 国成人网| 91精品婷婷国产综合久久| 狠狠综合| 人人做天天爱| 色欲婷婷五月天| 五月丁香六月激情综合| 99爱操| 婷婷99丁香| 婷婷九月丁香| 另类激情网| 99精品久久久久| 九九热在线观看视频| 男女啪啪做爰高潮无遮挡| 亚洲天堂AV综合网| 狠狠看狠狠| 久久精品视频9| 夜夜爱伊人| 色噜噜狠狠色综无码久久合欧美| 五月丁香婷婷狠狠操| 9 99免费视频| 第四色婷婷色五月| 亚洲中文字幕AV| 色五月激情五月| 九色无码| www.亚洲激情| 五月婷婷综合网| 成人在线观看精品| 久久久婷婷婷| 婷婷五月丁香五月综合网| 色屌丝中文字幕| 伊人网色婷婷五月天| 欧美大道不卡| 亚洲一区二区无码蜜乳av| 另类视屏| 色六月天| 天天爱天天爽| 热久国产| 深情五月天| 99亚州综合精品成人网| 在线不卡中文字幕| 久色资源网| 天天草天天爽| 99re热99| 99色精品| 北条麻妃伊人| 五月婷婷丁香五月亚洲色| 狠狠色综合网| 婷婷丁香精品视频在线观看| 五月丁香久久综合精品| 婷婷综合激情| 五月丁香婷草| 亚洲天天操| 国产精品涩涩涩视频网站| 97丁香五月| 俺去也在线官网| 人人爱国产| 夫妻超碰在线| 99爱视频免费看| 六月激情网| 激情图片99| 色婷婷a三区麻| 激情综合五| 色月九九| 婷婷五月天综合久久| 色婷婷狠狠久久综合五月| 丁香六月婷婷开心| 色色激情五月天| 五月 激情视频| 欧美丁香婷婷五月天| 欧美Va在线| 深爱激情五月天| 熟女网站久久| 99在线视频资源| 色综合久久88色综合天天| 热久久视频99| yjzz亚洲国产| 思思久久99热只有频精品66| 亚洲丁香婷婷| 久久成人人妻| 9999热精品| 亚洲色激情| 黄色激情网站在线观看| 日日插日日干| 婷婷丁香五月天熟女丝袜| http://www.sd-xiangsu.com/| 日本欧美成人片AAAA| 天天拍夜夜撸| 国产精品第一国产精品| 婷婷丁香激情五月天色色| 熟妇内谢69XXXXXA片| 5月色亭亭视频| 色五月婷婷在线| 五月亚洲激情| 久久久婷婷五月天| 婷婷六月五月| 99久久视频| 狠狠狠狠狠狠| 久久新地址| 日韩婷婷| 激情欧美婷五月| 狠狠干综合| 婷婷5月开心6月| 9久热精品在线视频| 天天操夜夜爱| 久久久久久久久久久月丁| 99精品免费视频| 大香av| 五月婷婷激情性爱| 色五月婷婷五月丁香五月激情五月视频 | 99久久婷婷国产综合| 午夜婷婷丁香| 亚洲 在线 另类| 五月婷色啪| 丁香五月97视频| 亚洲熟妇无码乱子AV电影| 中文资源在线a| 99热精品在线播放| 婷婷性爱无码视频| 激情五月婷黄版| 9久久久久久久久久久| 婷婷成人综合| 在线观看视频1区| 婷婷五月天综合在线| 99riAV国产精品视频| 色色色色色色网| 六月婷婷色五月| 国产女生爱爱AA| 亚洲AV中文在线| 欧美日韩一a.无| 色伦专区97中文字幕| 午夜激情五月天| 中文精品在| 丁香五月社区| 天天插插天天| www.主妇. com| 综合福利网| 丁香婷婷五月综合| 五月婷婷激情色情网| 任我肏视频精品| 色婷婷免费观看| 天天操夜夜夜拍拍拍| 日韩无码性爱| 中文字幕日产A片在线看| 97色色色色色| 久久成人性爱| 久久免费丁香| 懂色av粉嫩av蜜臀av| 99色| 91精品国产综合久久密臀| 91丨九色丨熟女|老版| 日韩中文字幕| 久久停停超碰| 精品五月天| 99这里有精品久久97| 九 九九九AV| 久99| 天天爱综合网| 影音先锋秋秋五月婷婷| 激情综合网五月婷婷| www...com黄在线观看| 特黄三级片| 久久久久人妻精选| 99热久只有精品首页| 婷婷五月天AV在| 国产精品久久久爽爽爽麻豆色哟哟| 香蕉人在线香蕉人在线 | 亚洲综合丁香五月| 丁香婷婷六月婷婷六月婷婷六月婷婷 | 五月婷婷色综图片| 久久这里只有精品视频15| 亚洲第一第二网站| 久久丁香五月| 激情五月天偷拍综合网| 欧美va亚洲va在线播放| 天堂爱爱| 99re66热这里只有精品| 日本色天堂| 97se在线视频| 五月天丁香久久综合| 日韩啊啊啊| 99热免费| 思思热这里只有精品| 狠狠色噜噜狠狠狠888了| 天天做天天爱天天爽夜夜揉| 97干综合网| 狠狠色噜噜狠狠狠狠狠色综合久久| 婷婷色婷婷| 秋霞性爱AV| 欧美Va婷色| 五月婷婷二月丁香| 久久久精品人妻录| 六月天六月婷| 99热精品网| 综合激情五月天| 九九性爱网| 精品激情| 思思99热在线| 99亚洲综合| 久久久激情| 桃色激情五月天| 99小视频在线观看| 亚洲天堂无码| 丁香六月婷| AV在线收看| 婷婷久久婷婷色五月| 亚洲天堂婷婷| 丁香五月婷婷www..com| 日本英国美国欧美亚洲国产精亚洲日韩精品在线观看 | 婷婷久久欧美| 日本久碰| 一区二区三区XXXXXX| 日本少妇AA一级特黄大片| 色婷婷丁香AV综合| 天天综合91入口| 日日噜噜久久婷婷五月天| 五他月天啪啪啪| 天天网曰日曰夜夜综合永久免费| 五月天婷综合| 91中文在线| 五月天五月色婷婷综合| 亚洲五月综合色播| 中文字幕乱轮| 婷婷色操| 99久热这里只有精品| 性一交一乱一交A片久久四色| 丁香五月色色| 色婷视频| 狠狠久久婷五月综合色| 亚洲精品另类| 丁香六月激情四射| 婷五月天天| ...婷婷国产成人亚洲日韩| 狠狠狠人妻| 成人电影丁香六月天| 第五色色色婷婷| 色综合中文| 久久伊人大香蕉| 99性爱视频| 九九色婷| 丁香五月婷婷亚洲色图| www.婷婷网| 色高清无码视频| 丁香五月成人社区| 啪啪啪大香蕉| 九月丁香八月婷婷加勒比| 91传媒无码人妻精| 久久久网站| 五月丁香色五月| 综合五月网| caop在线| 婷婷五月激情黄色| 玖玖在线视| 最新激情五月天| 成人五月天视频播放| 国产在这里只有精品| 国产成人99久久亚洲综合精品| 99热精品在线观看| 色九月综合网| 五月婷婷色影院| 丁香女人五月天| 色婷婷综合网站| 丁香久月| 亚洲热久久| 五月停停999| 五月花婷婷| 色婷婷小视频| www久久久| 婷婷.com| 色五月天电影| 91九九热| 久久久久久草黄色片AV在线观看| 五月天激情亚洲| 五月天com| 五月久久丁香| 91精品91久久久中77777| 丁香婷婷色五月天| 深爱激情六月天| 热婷婷av| 九九99视频精品| 深夜A片| 欧洲色色| 麻豆精品| 夜夜资源站| 99re在线这里只有精品视频首页| 五月天开心激情综合网| 亚洲自拍天堂| 九九视频精品在线免费| 啪啪啪大香蕉| 日韩成人电影Av| 九九热只有这里是精品| 婷婷的99视频网站| Www.久久| 亚洲AAAA网| 99热这里是精品| 2015在线中文字幕| 初夜av| 人妻熟妇国产精品| 激情五月婷婷视频一区二区三区| 婷婷开心青青草| 99re最新地址| 极骚大香蕉伊人| 国产婷婷色五月| 七七色色综合| 色爱爱综合网| 婷婷五月骚厕所| 26uuu精品一区二区| 99视频在线观看视频| 日韩av大全| 六月激情婷婷| 久久精品五月天| 婷婷五月色播| AV大片在线观看| 999热成人在线综合网| 综合激情五月丁香| 亚洲精品视频在线| 激情文学久久| 97色天堂| av网址在线| 久久婷婷五月综合一| 色综合xx| 久久99热免费| 狠狠色婷婷777| 日本99久久| 激情99| 99狠狠操一| 综合久久五月天| αv中文字幕在线观| 色五月丁香一区在线| 久久婷婷成人综合色怡春院| 亚洲色色色色色色色色色| 天堂综合久| 91嫩草久久| 欧美va亚洲va在线播放| 狼人久草| 天天爽天天弄| 亚洲精品V天堂中文字幕| 色色色色色级无码| 99热官网| 欧美综合在线五月天色婷婷| 欧美成人在线观看| 热久久66| 99@久久@99精品视频| 中文字幕日韩无码制服诱或| 五月天婷婷无码| 五月天色视频| 欧美在线视频9| 精品久久这里热66| 人妻AV在线观看| 九九婷婷综合| 日韩成人av在线| 激情五月五月婷婷| 日韩狠狠色婷婷| 日韩精品视频中文字幕| 国产日日操夜夜操的肉棒视频| av一区免费看| 超碰人人干| 欧美在线97| 丁香色婷婷| 婷婷五月天视频小说| 99福利视频导航| 深爱激情丁香| 91久操| 免费做A爰片77777| 26uuu.| 日韩中出视频| 婷婷五月婷婷| 五月天社区| 丁香六月婷婷综合| 日韩高清久久| 色婷婷久久| 夜夜操夜夜姧| 六月丁香天堂| 99在线观看精品| 热九九在线| WwW色婷婷| 丁香狠狠色婷婷| 激情综合五月婷| 日韩限制级大尺度黑料泄密大尺度视频一区二区在线观看 | 亚洲成人在线五月天| 香蕉操亚洲| 九九色精品| 天天色综合图片| 97碰| 九九热视频精品999| 婷婷综合在线| 激情五月图| 99五丁香月| 六月 丁香 视频| 色五月天在线| 操人无码| 五月天小说激情| 中文无码婷婷| 天天色,天天日,天天做| www激情| 色吊丝99| www婷婷| 99这里| 婷婷色无码| 九月激情综合婷婷| 天堂无码人妻精品AV一区| 91人操人人人操人| 玖操97| 色五月色五天色情网址| 日日干日日| 亚洲激情久久| 久久婷婷在线| 婷婷爱在线观看| 丁香视频| 亚洲第一成人无码A片| 超碰在线精品| 色五月天本日| www。五月天。com| 久久人人九九| 日韩成人中文| 丁香六月色香蕉视频| 九九综合九色欧美狠狠| 99热色精品| 婷婷五月丁香超碰| A久网| 这里只有视频精品| 亚洲永久四色| 狠狠色狠狠爱| 日韩成人无码片| 黑人糟蹋人妻HD中文字幕| 99操| 国产精品色婷婷99久久精品| 五月婷婷丁香在线| 天天综合干| 五月天婷婷色色| 亚洲AV网址| 日韩五月婷婷| 99久久天堂婷婷| 国产婷婷婷| 丁香五月性| 激情婷婷五月| 日本久久高清| 久久五月网| 五月丁香色六月激情干大屄| 丁香五月天天高清在线| 五月婷婷综合网| 久久久久网站| 九色七七| 九九九九九九毛片| 操操精品| 婷婷五月天午夜激情影院| 91综合网| 99玖玖精品| 97ai婷婷| 男人天堂AV在线一区二区| 色综久久久| 丁香99| 亚洲无码影音| 丁香狠狠色婷婷久久无码视频| 亚洲无AV在线中文字幕| 99热这里只有精品9| 亚洲va成人va成人va在线观看| 99热国产精品| 色吧五月婷婷| 五月婷婷激情综合网| 五月婷婷之综合激情| 久婷| 久久精彩视频| 99这里有精品| 亚洲精品久久久无码| 少妇做爰免费视看片| 狠狠精品干练久久久无码中文字幕| 9色在线| 国产精产国品一二三在观看| 风流少妇A片一区二区蜜桃| 欧美性猛交99久久久久99按摩| 亚洲妇女熟BBW| 黄色国久久| 免费碰碰视频久| 婷婷久久天堂网| www.99久久久久99| Caoporn公开| 亚洲xx网| 99久久五月丁香野外| 丁香五月欧美色综合| 99网址在线看| 激情婷婷色小说| 五月丁香婷婷五月色| 99热久草| 99视频久久| 六月丁香综合| 91碰在线| 91精品丝袜久久久久久| 国产99久久久国产精品免费看| 1024AV视频| 51XX嘿嘿午夜无码| 色播丁香| WWW色综合| 这里只有精彩视| 婷婷五月天天aV| 九九热99熟女| 影音先锋一区二区三区| 精品无码久久久久久久久| 久久人人添人人爽添人人片αV| 91性人人| 色婷婷五月天| 以及AA大片看看| 67194线路二在线观看| 国产91九色| 2017人人操| 99热这里只有精品98| 天天激情视频| 九九在线视频| 无码人妻丰满熟妇奶水区码| 九九综合图片网| 91超级碰| 五月婷婷在线综合| 九九精品综合| 精品亚洲国产成AV人片传媒| 九热电影av| 婷婷丁香69精华| 久久激情五月天| 人妻人人操| 五月婷婷久久大片| 久久久性爱网| 青草热视频这里只有精品| 天天噜| 在线理论片| 91丨九色熟女丨首页| 性婷婷| 亚洲婷婷欧美婷婷| 韩国真做片在线观看| 色色色色色色五月婷婷| 在线五月色播| 激情五月丁香六月综合AVXXXX| 免费观看18视频网站| 一级性爱大片| yazhouzonghesese| 天天综合网91| 丁香五月熟女| 99精品热视频只有精品10| 99免费| 99色视频| 久久综合五月天| 欧美天天干天天草| 大香蕉啪啪啪| 婷婷六月偷拍| 婷婷五月综合欧美在线播放| 91超碰在线播放| 日韩ww| 激情五月婷婷色色| 黄色AV日韩| 国产精品A片| 婷婷综合五月| 影音先锋偷偷色男人站| dingxiangtingtingliuyue| 婷婷婷婷婷婷婷婷| 综合婷| 久久婷婷综合五月天| 天天操夜夜玩!| 91疯狂操操操操| 狠狠操狠狠操AV| 这里只有精品免费视频在线观看| www一起操| 少妇2做爰HD韩国电影| www99热| 久热这里只有精品性色AV| 在线超碰免费| 色综合九九| 岛国av电影网站| 丁香五月婷婷激情四射| 青青草国产亚洲精品久久| 99视频这里只有精品10| 九九热亚洲中文在线观看免费| 97色 五月天丁香| 综合大香蕉| 五月的丁香六月的婷婷| 婷婷九月亚洲| 国产做爰视频免费播放| 丁香五月综合激情啪啪| 97色伦另类图片小说视频| 伊人狠狠色婷婷综合丁香一区| 丁香五月偷拍| 天天看A片| 午夜丁香久久久久久| 亚洲色啪| 五月天天爽| 婷香五月网在线| 国产综合81p| 国产精品人成A片一区二区| 激情亚洲婷婷| 久久婷婷六月综合资源| 久热一本| 野外99热| 国产亚洲精品久久久久久郑州| 色色国产| 999热成人在线综合网| 色五月婷婷中文字幕| 九九九九中文字幕| 人妻久久久| 五月天综合色| 国产精品色一哟哟| 九九综合久久| 中文字幕欧美久久| 黄色中文字目| 久久综合激情| 看片视频在线免费日产在线看| 另类图片 五月激情| 另类专区在线| 九月丁香八月婷婷久久综合久97| 色色色九九九五月婷婷| 九九热精品视频| 猫咪伊人久久| 深爱五月婷| 色五月aV| 久久久人妻不卡| 亚卅毛片| 婷婷综合日本| 国模九区| 丁香婷婷五月份| www.夜夜操.com| 成人av在线电影| 99热这里都是精品| 亚洲色无码| 激情都市五月天| 丁香婷婷精品视频| 日夜操B| 26uuu偷拍亚洲欧洲综合| 最新日韩AV中文字幕| 丁香五月婷婷五月| 99亚洲天堂| 另类A片| 综合网激情| 五月花综合视频| 婷婷六月激情丁香| 久久综合伊人综合在线| 99re这里只有精品9| 99综合视频| 99在线69| 色婷婷五月综合在线| 久婷自拍视频| 91精品久| 亚洲天堂制| 激情综合五月丁香六月婷婷| 丁香,开心成人,久久| 国产成人精品一区二区三区视频 | 激情综合五| 啪啪啪综合网| 99操逼视频| 婷婷六月激情| 丁香激情久久| 国产97色在线| 99精品热视频| 97婷婷狠狠| 九九操操| 99免费热视频在线| 91操人| 人人爱操| 丁香五色月婷婷网| 天天上天天爽| 婷婷激情五月天网站| 密黄站| 婷婷综合网在线| 婷婷免费成人视频| 九九热思思热| 亚洲 小说 欧美 激情 另类| 丁香五月成人在线| 99热这里只有精品23| 婷婷激情五月综合基地| 大伊久久| 欧美激情综合色综合| 久久久久丁香婷婷五月天| 五月激激激情综合网| 日日撸夜夜操| 黄色五月婷婷| 99热亚洲精品| 99热这里都是精品| 国产无套精品一区二区| 蒲京久久无码视频| 亚洲精品成人片在线播| 欧美日本高清视频99| 丁香五月婷婷av| 99热老网站| 色99视| 丁香五月冃欧美| 天天爽免费视频| 91成人看片| 99九九久久| 99国产精品久久久久久久久久久| 五月婷婷综合激情小说| www.夜夜爱.com| 日本99视频精品免费播放| 三级毛片7979| 人人草成人视频| 思思w99| 婷婷六月丁香欧美视频在线| 欧美精产国品一二三区| 高清无码入口| 久久精品A片777777| 久热爱大香蕉在线蜜臀悦色| 色欲婷婷五月天丁香| 五月天婷婷综合久久| 久久草婷婷丁香网站| 丁香五月综合在线视频| 久热 91| 九九性视频| 在线亚洲综合| 亚洲综合婷婷| 丁香五月第九色| 天天爱夜夜爽| 精品久久9| 欧美性生交XXXXX无码小说| 成人无码中文| 超碰成人在线观看| 丁香五月狠狠综合欧美| 亚洲成人在线五月天| 成人国产综合| 日本三级韩三级99久久| 激情九月婷婷九月| 日本婷久久| 婷婷综合网伊人| 丁香五月Av| 五月天开心网| 96色婷婷| 色色丁香| 色色色.COM| 色综合丁香| 伊人大综合| 婷婷的99视频网站| 激情丁香五月激情婷婷| 欧美色97| 操操操97| 五月激情网站| 日韩六六久久电影| enecarbon-materials.com污K127封锁请涟系@wip1688 | 天天干天天日日| 欧美色性色好| 精品夜夜澡人妻无码AV| 五月天婷综合| 久热re视频在线观看网站| 综合色99| 天天色综合网吨吧| 五月天狠狠| 超碰97色| 夜夜操夜夜爽| 1区2区视频| WWW色五月| 99人妻碰碰碰久久久久禁片| 色色 9| 六月丁香五月天| 9 1大香蕉| 人人舔人人色人人高潮| 激情无码网| 影音 五月 婷婷 久久| 99热国产| 激情伊人五月天| 成人综合网站| 久久大香蕉视频| 热久久视频99| 99热都是精品| 99噜噜噜| 五月丁香另类网| 婷婷五月激情网| 久久超级碰视频| 天天干天天操天天爱| 婷婷激情综合| 99热热热国产超碰| 丁香五月在线观看完整版| 夜夜躁爽日日| 二级黄色毛片| 久热网站| 亚洲经典三级| 丁香五月婷婷久久综合激情网| 色无码| 射满了还射免费在线观看 -午夜版全集-新视觉影院 | 男女99免费视频| 婷婷伊人五月丁香天堂网| 色婷婷色久综| 五月天综合视频| 91干在线| 吉澤明步Av一區二區| 欧美色男人网站| WWW色五月天| 91久久1118| 超碰国产AV| 人人爱人人摸人人澡| 国产成人精品一区二三区熟女在线| 成人 在线 日韩| 婷婷丁香亚洲色综合91| 超碰啪啪网| 夜夜撸天天日| A短视频免费在线观看| 五月亭亭六月色| www.zbzhongsen.com| 另类图片五月天婷婷| 丁香六月婷婷色XXXX| 少妇熟女视频一区二区三区| 久热久| 五月婷婷影| 丁香五月婷婷亚洲色图| 丁香婷婷色| 婷婷五月另类网站| 久色五月| 超碰成人黄色网| 天天干-天天日| 亚洲蜜桃精久久久久久久久久久久| 丁香五月综合高清在线| 97人妻碰碰中文无码久热丝袜| 91成人电影| 五月丁香婷婷深深爱| 伊人大香蕉在线视频| 丁香五月天之婷婷影院| 五月色婷婷夜色| 久久视频这里有精品99| 久久久九九九 99| 都市激情五月婷婷亚洲| 久久R激情| 夜夜爽天天日| 色色欧美色色色| 久久这里99| 狠狠婷婷综合| 欧美亚洲婷婷五月| 日本三级第一页| 五月天六月婷| 婷婷激情五月天激情小说| 欧美丁香婷婷五月天| 激情AV中文| 久久久免费精彩视频| 婷婷色中文| 久久HD| 婷婷五月色情天| 色综合99| 天天肏天天插| 五月色情| 激情五月天色婷婷| 99久久高清视频| 激情五月,婷婷五月,丁香五月| 六月婷在线| 五月天婷婷色| 综激情网| 噜噜在线| 日本ww亚洲| 六月丁香网| 婷婷激情五月综合在线视频| 色婷婷精| 久久久久久久人妻| 色九月欧美| 成年人丁香五月| 五月婷婷开心色伊人| 国产精产国品一二三在观看| 青青草原福利在线| 五月亭亭欧美女人| av色婷婷| 六月激情婷婷色| 五月桃花网综合| 婷婷丁香五月亚洲| 久青操| 色播播五月天| 色色婷婷综合网| 婷婷丁香视频| 夜夜操天天干| 天天操夜夜玩!| 任你搞在线观看视频| 人妻久久婷婷| 久久这里这里有精品免费视频| 国产午夜精品一区二区三区四区| 欧美va在线| 99热这里都是精品| 婷婷五月激情综合| 久久精品66| 五月天综合激情网| 丁香五月天视频| 五月丁香久久呀| 色婷婷AV在线| 六月婷婷av| 日本婷婷丁香五月| 久久全色| 另类激情综合| 激情五月天小说视频| 亚洲婷婷婷| 一本大道嫩草AV无码专区| 99热国产在线| 五月丁香激情四射| 久久久天堂国产精品女人| 丁五月激情视频免费| 操操操操操操婷婷五月天| 一操久久| 成人五月天婷婷| 射婷婷中文字幕| 丁香五月欧美色综合| 国产视频久色| 爱狠射| 在线观看中文字幕| 91精品国产综合久久密臀| 欧美色偷拍| 精品国产乱码久久久久夜深人妻| 激情文学五月丁香六月婷婷 | www激情| 五月丁香婷婷成人综合网| 色婷婷综合视频| 丁香五月婷婷社区| 97碰在线| 99热日韩| 五月欧美色播| 51精品国内探花| 婷婷色导航| www.天天干| 激情欧美婷五月| 色综合大香蕉| 婷婷综合九色伊人| 亚州色色色| 亚洲AV色婷婷人禽五月天| 久久五月天大美女| 成人啪啪色婷婷久| 亚洲欧洲中文日韩久久AV乱码| 五月丁香成人小说| 五月天婷婷伊人| 久久激情综合| 中文字幕丰满乱孑伦无码专区| 人妻久久久久久久| 播五月,色五月,开心五月播放器| 五月天婷婷丁香花| 美女黄频aⅴ视频| 高清 码 免费看片短视频| 五月婷在线| 曰曰久久| 日韩在线五月天婷婷| 五月天婷婷午夜丁香| 伊人综合色干| www.夜夜| 91狠狠色| 五月天成人在线视频网站| 丁香五月激情综合网激情五月| 色99在线观看| 色吊丝av中文字幕| 日韩av手机在线观看| 夜夜骑夜夜撸| 这里只有精品无码| 精品久久久久久久人妻| 国产阿姨日皮艹逼内射视频| 成人精品人妻| 丁香五月天社区婷婷| 国产午夜精品一区二区三区四区| 人妻久久久久久|