免费国产精品自在自线-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
返回資訊列表
丁香六月色婷婷| 成人va在线观看视频| 能看的av| 人人舔人人| 91精品久久久久久| 91在线看免费 九九九九| 九九热视频精品| 四色女婷婷| av无码电影| 欧美三级巜人妻互换| 99热免费观看| 日本五月天婷婷丁香| 色一情一乱一乱一区91| 伊人网碰碰| 成人免费黄色短视频| 日韩精品一品二区三区的使用体验| 天天综合情| 91操女| 婷婷午夜天| 婷婷五月天高清无码| 亚洲五月天,激情视频| 亚洲蜜乳AV| 99无码| 97干在线播放| 久久婷婷丁香| 久久久99久久| 五月丁香久久| 婷婷五月天激情网| 久99| www.五月丁香| AV九九| 另类图片色五月| 亚洲精品激情| 欧美日韩成人高清在线| 操操自拍| 婷婷五月六月丁香| 超碰人人在线| 人妻AV中文系列| 丁香六月综合激情| 拍真实国产伦偷精品| 大香蕉99热| 97操碰在线视频| 亚洲色无码| 久久婷婷五月激情网站| 五月丁香花开综合网| 午夜 外网 精品 在线| 婷婷丁香五月天综合AV| 伊人狠狠狠综合| 情欲综合网| 激情五月伊人婷婷| 五月丁六月婷| 婷婷五月丁香六月| 激情综合网五月婷婷| 色色网站在线| 激情婷婷色色| 五月婷婷爽爽爽| 国产古装妇女野外A片| 亚洲色婷婷| 五月天婷婷小说| 婷婷五月天影院| 中文字幕精品在线观看| 97av在线视频| 国产黄色大片| 九九99精品| .操區COm| 99热12| 综合图区激情| 久久伊人婷婷| 免费视频WWW在线观看网站| 亚洲成人综合在线| 97干在线免费| 九玖视频这里只有精品| 亚洲激情色色| 久久久香| 老司机视频lsj爱就色| 色色六月| peg 2区三区四区的| 六月五月久久丁香| 天天干天天干天天干| 99在线观看| 色五月婷婷网| 91精品又长又大又粗又爽又猛| 五月色色网| 丁香婷婷激情综合五月激情| 热思思| 成人电影AV在线观看| 婷婷色导航| 亚洲亚洲人成综合网络| 色色爽爽天天| 第四色婷婷丁香五月| 原琪琪色影院| 一本到不卡高清DVD| 丁香亚洲色综合| 涩五月婷婷| 五月天开心色情网| 人人干99| 亚洲电影中文字幕| 情欲综合网| 久久久久人妻精品| 91色性感五月婷婷丁香| 狠狠色五月激情| 人人草人人视| 亚洲精品又粗又大又爽A片| 五月婷婷综合成人| 久久五月丁香激情综合| 99久久婷婷国产综合精品草原| 国产精品18久久久| 日本久久婷| www.五月激情红色| 日本一级黄色电影| 99热e| 99久久综合精品五月天| 五月婷婷五月天| 色五月婷婷丁香凹凸| 色婷婷五月色| 五月婷婷视频在线观看| 丁香五月激情啪啪综合| 六月丁香婷婷网| 欧美激情VA永久在线播放| 开心五月婷婷| 日日操夜夜操狠狠操| 亚洲激情综合| 色婷婷色婷婷五月| 亚洲国产精品二二三三区| 色婷婷综合在线| 五月丁香六月婷婷中合网| 亚洲男女激情| 久人人操| 69色婷婷| 狼人婷婷久久| 97干欧美| 五月婷网| 99无码| 日韩久久视频| 激情综合网五月激情| av在线观看网址| 色婷婷丁香五月丁香| 99ri精品视频在线观看| 五月天激情四射| 99热这里只有精| 五月婷婷我| 久久久人妻| 色碰碰视频| 夜夜爽天天干| 日本WWW九九九| 婷婷五月天成人小说| 亚洲人操亚洲人| 丁香五月婷婷姐| 久久久婷婷婷| 青青草护士中出内射-欧美电影在线天堂新版| 激情五月六月| 久久综合色五月| 五月婷婷综合在线视频小说| 热久国产| 一起草AV| 亚洲婷婷激情五月天| 欧美成人猛片AAAAAAA| 综合五月天亚洲婷婷| 色五月色五天色情网| 六月婷婷香蕉| 色色射| 久久99久久99久久99人受| 欧美久久婷婷| 丁香五月另类小说在线阅读| 五月天大香蕉婷| 五月天社区狠狠| 丁香九月色| 欧美色爱五月天| Caoub青青超碰 | 国产夫妻操逼内射视频| 五月丁香婷婷钟和色图| 色综合久久88色综合天天99| 伊人久久五月天| 婷婷五月激情小说| 丁香美女主播视频在线观看| 丁香九月综合| 极品少妇XXXX精品少妇偷拍 | 天天色2017| 久久成人天| 久久国产成人9999久久久久| 九九热大香蕉| 婷婷亚洲丁香五月| 日本久久99久久| 九九99久久| 色五月婷婷天天干| 九九99偷拍视频| 九九热免费视频| 99九九在线精品热动漫| 中文毛片无遮挡高潮免费| 精品无码视频| 婷婷色播婷婷| 五月婷婷欧洲| 青草五月天| 激情五月综合免费| 久久免费操| jiZZdr| 婷婷情色激情| 噜一噜免费视频| 国产肥白大熟妇BBBB视频| 久久aaaa片一区二区| 狠狠人人| 久久99综合| 成人免费高清在线播放| 亚洲欧洲中文日韩久久AV乱码| 狠狠干五月丁香综合网| 六月婷婷网| 日韩在线99| www.99热在线| 婷婷五月天无码熟女| 思思9久久| 日韩精品二三区| 亚洲免费观看高清完整版AV线| 四色99久久| 丁香五月激情综合在线观看| 欧美大道不卡| 免费无码毛片一区二区A片| 丁香五月 六月婷婷首页| 色亭亭丁香五月天| 99热官网| 天天做天天爽| 色播五月丁香婷婷| 99热线观看9| 色色日本| 色婷婷激情| 激情色中文| 182tv992tv人之初午夜免费观看| 91一起艹| 五月天激情电影| 亚洲av成人在线| 亚洲成人另类| 精品婷婷| 香蕉视频91| 天堂爱爱| 狠狠爱激情网| 色婷婷久久9.com| 色婷婷成人| av人人操| 五月天欧美 另类小说| 久久色午夜在线导航| 91精品婷婷国产综合久久| 丁香五月激情综合网激情五月| 亚洲成人AV在线| 婷婷五月天网| 色婷婷天堂| 九九热思思热| 色五月综合婷婷久久综合婷婷久久综合婷婷久久综合婷婷久久 | 五月丁香婷婷综合久久| 96精品国产综合久久久久久| yazhoujiqingav| 色婷五月| 2017狠狠干| 激情综合网 激情五月天| 另类激情五月| 97久久五月丁香婷婷| 少妇AB又爽又紧无码网站| 五月丁香五月婷婷| 免费五月婷婷网| 噜综合| 人人性久久| ztEJj| 人妻中文在线| 色播五月天激情| 久色| 天天日日夜夜| 五月天激情丁香| 日日操人人操| 欧美va| 丁香5月激情网| 九九色之九九色之88| 丁香五月综合狠狠| 色和综合网| 99自拍视频| 亚洲欧美成人在线| 亚洲综合成人网| 九九热视频这里只有精品| 婷婷五月丁香综合人妻| 九九精品视频在线6| 天干天天干天天天天天| 人人色性网| 操碰97| 日本三久久| 久久大香蕉伊人| Www.se.久久| 日韩av变天就操逼不卡区| 天天干天天干天天| 免费观看欧美成人AA片爱我多深| 免费看欧美成人A片无码| 97人人射| 99视频| 99热在线观看| 骚逼视频一区2区| www,奇米影视| 亚洲成人AV一区在线观看| 97超级碰人人| 五月丁香人妻| 五月天久久www| 亚洲综合另类| 亚洲天堂99| 91色婷婷综合久久中文字幕二区| 人妻狠狠操| 亚洲国产精品成人免费一区久久久在线观看AAAA | 99久超碰| 天天久久66xxx| 99久久丝| 色噜综| 俺去啦综合网| 成人在线综合| 五月开心网| www..com色爱| 激情小说视频图片网| 26uuuuuuuu国产| 精品亚洲VA网站| 欧美丁香五月夫妻天| 欧美性丁香色色五月天干干| 五月丁香久久综合| 98国产精品综合一区二区三区| 国产AV一区二区三区最新精品| 97热91| 九热网站| 人人操AV| α久久| 婷婷五月天激情五月天深爱五月天| 丁香六月色婷婷| enecarbon-materials.com污K127封锁请涟系@wip1688 | www久| 久久五月天激情婷婷| 激情五月丁香色婷婷| 九九婷婷五月天影视| 噜噜噜噜噜色| 亚洲欧美综合7777色婷婷| 熟女激情五月天| 日本视频久久| 色娸娸综合网| 2020夜夜操天天爽| 超碰超碰在线| 婷婷久久夜| 五月天激情AV| 五月天激情图片| 五月天网址在线刘玥| 色婷婷成人久久| 九九99免费理论| 夜夜躁狠狠 | 99精品热视频| 激情五月天婷婷视频| 五月天六月色| 全部老头和老太XXXXX| 国产操肏网站| 黄色成人网站在线播放| 六月婷婷狠狠色在线观看| 色永久| 欧美三级欧美一级| 青青草原亚洲久| 丁香五月另类色婷婷麻豆| 天天日夜夜夜操操操操| 丁香九月久久| 激情五月天婷婷色色色色色色色色色色色| 五月伊人综合| www.五月婷婷| 91久久国产综合久久| 这里只有精品视频222| 五月丁香另类网| 日本欧美在线| 一级二级色大片| 一本道综合网| 久久久性爱视频| Aaa久久| 久久狠狠欧美| 日日夜夜干| 欧美69久成人做爰视频| 99免费视频久久| 五月花激情| 99综合网| 99re在线观看| 久久婷婷五月综合啪| 最新高清无码专区| 婷婷激情中文综合| 五月天色色网站| 丁香五月天婷婷大香蕉| 色婷婷六月开心中文字| 操碰91| 六月婷婷啪啪| 五月综合激情视频在线| 九九伦子片| 五月丁香五月丁香| 天天操天天曰| 色综合丁香| 亚洲久久激情| 91干网| 婷婷丁香五月天小说| 伊人激情| 99久热在线精品| 色偷偷五月天| 超碰伊人碰婷婷五月| 99热这里只有精品13| 欧美婷婷综合| 9久视频| 色综合九九色综合88| 日韩精品电影| 狠狠综合网| 一区二区你懂的| 婷婷五月婷婷五月天| 五月婷婷久久综合| 狠狠香婷婷五月| 婷婷色导航| 26uuu丁香婷婷五月| 丁香六月久| 99久久超级| www.日韩艹| 男女啪啪做爰高潮无遮挡| 99ri精品| 丁香色婷婷| 天天艹天天综合网| 色婷婷影院| WWW丁香五月| 东京热免费视频| 久久五月婷婷电影| 97色色网| 久99久热只有精品国产99| 欧亚成人A片一区二区| 亚洲人人96@| 99啪啪| 日曰躁夜夜躁2026| 九玖欧洲亚洲| 色很久综合| 99色色网| 99综合久久| 深爱五月激情五月| 国产探花AV在线| 久久九九激情五月天| 色5月婷婷| 五月婷九九草| 五月丁香久久网| 26uuu青青| 做爰丰满少妇1313| 亚洲欧美国产高清vA在线播放| 激情网色五月| 日本色道视频网站| 亚洲欧洲自拍图片专区五月天| 天天日天天久久青青| 26uuu亚洲精品国产| 美国不卡视频| 99热| 五月丁香中文字幕| 亚州操操| 51精品国自产在线| 日狠狠| 最新色色五月天| 大香蕉久操| 五月婷婷之激情五月| 婷婷五月欧美| 色色色免费视频| 99这里只有免费的小视频在线观看| 99精彩视频网站在线| xxx.色婷婷| 超碰在线视屏| 五月丁香婷婷欧美色图视频五月丁香777电影| 亚洲人妻五月丁香婷婷| 天天色丁香| 欧美大肥婆大肥BBBBB| 丁香五月婷婷骚视屏| 狠狠se| 99热只有| 综合婷婷五月天| 91精品综合久久久久久五月丁香| 99热综合在线观看| 色噜噜狠狠一区二区三区| 精品99网站| 538任你爽视频不一样的| 色色射| 99青青草| 大地资源色婷婷视频在线| 五月婷婷开心丁香| 六月色日韩| 9 9热这里有精品| 99这里有精品| 五月丁香婷婷婷激情爱爱| 五月天伊人av| 国产1区2区3区| 久久久99精品免费观看| 五月丁香婷婷综合网| 欧美色小说婷婷| 久操福利| 五月深情久久| 亚洲精品无码99热| 婷婷欧美| 高清不卡一区| 在线综合网| 丁香久色| 久久久人妻不卡| CAOBIBI| 亚洲亚洲人成综合网络| 色99在线| 九月av| 天天射综合网夜夜操| 国产成人网| 亚洲欧洲一二| 大色鬼综合| 欧美va在线| 激情网五月天| 丁香五月天AV| 99色 色| 亚洲日本激情| 69热在线| 在线播放成人网站| 超级碰碰91| 五月丁香A片| 最近免费中文字幕大全高清大全1| 91人人网| 婷婷色啪| 综合久久高清| www.色九月| WWW,五月| 啪啪小说五月天| 秋霞簧片| 人妻 性久久久久久| 五月天伊人av| 欧美激情 日韩无码 婷婷 五月天| 99热在线精品播放| 久99热在线观看| 91碰九色| 色九九七七| 婷婷影院欧美| 丁香五月天激情四射网| 99五月婷| 综合色影| 婷婷五月天综合网| 色五月综合激情| 激情五月丁香社区| 丁香五月激情五月| 久热超碰| 色色五月天激情| 激情综合网色播五月| 99热这里只有精品在线观看| 欧美25p| 99在线精品视频| 激情丁香五月| 强辱丰满人妻HD中文字幕| 天天日天天舔| 日本熟妇乱妇熟色A片蜜桃| 丁香五月天社区| 国精产品一区一区三区免费视频| 亚洲亚洲人成综合网络| 色综合激情图区| 久久久久久久91| 五月做爱| 日韩精品超碰在线观看| 99九九在线观看免费| 久久婷婷色情7777网站| 丁香五月色情| 五月在在观看| 激情小说婷婷五月| 色五月婷婷大香蕉| 色色色无码| 五月天色五月| 99re久热| 狼友视频在线观看18| 久久五月天婷婷| 日本a片网址| 婷婷五月天.com| 色婷婷激情五月天在线观看| 成人在线日韩欧美| 五月天婷婷色色| 成人日韩欧美| 婷婷五月丁香性爱| 久久精品91视频| 性爱网久久| 五月天婷婷网站| 天天摸人人摸| 51XX午夜影福利| 婷婷五月天久久久| 色色六月| 日韩婷婷| 五月婷婷人妻| 色~性~乱~伦~噜| 欧美性爱五月天| 久久婷婷青青| 婷婷五月丁香综合| 九九热在线观看视频网站| 五月亚洲| 久99久视频| 婷婷天堂伊人| 久激情网| 天天日夜夜帕| 激情六月婷婷| 久热伊人在91| 韩国情人在线电视剧免费观看高清版全集| www,av好吊操| 五月天播播| 日韩国产AV播放| caop在线| 99热这里只有精品22| 色999亚洲人成色| 日韩99无码| 成人五月丁香社区| 天天爽夜夜爽| 天天干天天插| 91九色中文| 婷婷五月天成人动漫| 欧美色婷婷| 久久在线视频免费观看| 久久婷婷内射| 午夜婷婷六月天| 99免费在线| 俺去婷婷 丁香| 天天插天天狠| 超碰资源在线| 色五月婷婷亚洲| 天天干天天操天天爽| 91高潮喷水久久久久久久久| 亚洲激情免费久久| 亚洲无码成人| 九九热青青草| 五月噜噜| 欧美日韩91| 婷婷操超碰| 人人草人人爱手机视频看看| 久热伊人| 99re热精品在线视频| www.henhengan| 思思久久99热只有频精品66| 26uuu欧美日韩| 婷婷 伊人 久久| 日本婷婷激情四射中文字幕在线观看| 欧美va亚洲va| 伊人婷婷五月天| 伊人久久综合| 色播五月婷婷五月| 另类丁香五月天区图| www.狠狠操.co m| 91色噜噜狠狠狠狠色综合| 五月天啪啪网| 丁香五月天激情小说| 91超级碰| 欧美天天爽| 99视频35精品视频在线观看| 综合玖玖偷拍| 人人摸人人搞| 中文字幕欧美精品久久| 99热99这里有免费的精品| 三级三久久线久久99久目本WW| 超碰成人av| 色婷婷五月天在线观看| 日韩久久日| 热久久视频99| 男女啪啪视频久 9| 伍月婷婷六月丁香| 婷婷在线日韩综合| 婷婷四色成人综合色视| 亚洲综合色婷| 天天日天天日天天搞| 办公室少妇激情呻吟A片在线观看| 日本精品在线噜噜噜| 成人精品在线| 久久这里只有精品久久| 五月婷婷色色| 天天久久人人| av九九| 麻豆科斗777| 日本99热| 激情丁香五月激情婷婷| 熟女色色一区二区| 亚洲狠狠狠| 五月做爱| 殴美综合激情五月天免费视频| 欧美日韩国产日本精品四虎网网站物 | 日本一级淫| 色婷婷五月综合网| AV中文字幕夜夜操b天天摸bb| 91久久婷婷人人澡草| 97在线天堂| 99热都是精品| 99在线播放视频| 夜夜操天天干| 激情婷婷五月天伊人在线观看| 狠狠精品干练久久久无码中文字幕 | 99热这里都是精品| 综合激情伊人影视在线| 午夜少妇在线观看视频| 色五月激情基地| 婷婷五月丁香四射| 色五月涩涩婷婷| 亚洲精品亚洲人成人网| 日本乱子人伦在线视频| 五月六月激情| 亚州操操| 伊人激情AV一区二区三区| 色色色色色色97| 日本123区日韩欧美不卡在线看| 亚洲视频操| site:901-07.com| 99视频| 色99网| 色五月综合在线| 欧美性猛交99久久久久99按摩| 狠婷婷五月| 97色婷婷在线观看| 成片免费播放| 天天天操天天天日| 99久久久久| 热思思九九| 停婷丁五月在线| 九九综合视频在线观看| 9 7总站超级碰免费视频| 成人AV中文字幕| 日本女天天爽| 五月丁了香蕉综合| 九九热最新| 婷婷激情五月天在线视频| 9色在线视频| 五月永久激情| 综合激情在线| 久久五月婷天天干| 成人在线视频网| 色五月天激情| 啪啪91| 99精品综合在线| 色综合色色| 五月香六月婷| 综合五月草| 99视频在线啪| 国产精产国品一二三在观看| 久久婷五月综合| 五月婷综合性中心| 欧美精品999| 色九九九综合| 丁香五月影院| 人妻久热| 精品国产va久久久| 99爱这里只有精品| 97碰碰视频| 91嫩草国产线观看亚洲一区二区| 欧美激情综合| 久久天天| 丁香久久久| 伍月婷婷免费视频| 香蕉大综综综合久久| 男同91| 六月丁香AV| 百度一下国产精品A| 中文字幕不卡+婷婷五月| 五月婷婷激情四月| 日日操夜夜爽白洁| A片一曲| 91人人妻人人操| 最新无毒无码AV| 99色热| 8区视频在线| 亚洲天天| 操逼棍操逼| 婷婷六月插屄激情| 五月婷婷五月丁香综合| 色综合com| 激情伊人网| 丁香婷婷五月激情四射网| 九九综合| 99久久99九九99九九九| 九九RE视频在线精品| 天天爱综合网| 女高怪谈在线观看| 99热精品免费在线观看| 亚洲精品小视频| 久久ER视频com| 99在线观看亚洲| 99在线精品观看99| 色婷婷免费观看| 国产性爱一级| 性爱五月丁香| 99久久久久久www| 99内射视频| 婷婷日本色| 色吊丝99| 在线sebiav精品视频| 97日本在线播放| 超碰成人黄色网| 国产精品美女久久久久AV超清| 激情五月无码| 精品色情一区二区三区四区| 五月天天丁香婷婷在线中| 色色综合网站| 99热在线观看免费中文| 激情五月综合网| 色五月婷婷中文字幕| 日韩成人无码人妻| 九九亚洲视频| 五月丁香美女| 婷婷六月丁香久| 综合狠狠干| 玖操97| 青青草原99热| 婷婷五月色情天| 国产激情综合五月久久| 少妇人妻人伦A片| 国产.亚洲.欧洲视频在线| 99毛片| 99精品在线播放| 色色色色色综合| 日日夜夜干| 乱岳熟女50岁| 国内精品免费一区二区2009| 六月婷婷AV| 丁香五月激情综合婷综| 亚洲综合视频在线| 麻豆科斗777| ss99热| 97色色色色色| 久久性刺激| 激情五月丁香五月| 国产欧美日韩综合精品一区二区| 99精品丁香五月| 99精品网址| 99热99极品观看| 久久综合性| 另类图片五月天婷婷| 综合久久五月| 狠狠穞A片一區二區三區| 狠狠色狠狠| 99久久婷婷| 色五月色综合| 激情九月天天天天婷婷| 五月色综合| 色五月天在线| 91色在线 | 日韩| 亚洲综合色网| 中文字幕不卡网站| 婷婷久久丁香五月| 五月天 综合 在线| 色综合激情| 久久丁香五月天| 性生生活大片又黄又| 五月婷婷黄色毛片| 色五月丁香六月资源站| 久久性爰视频这里只有精品| 婷婷五月综合社区| 无码人妻少妇色欲AV一区二区 | 天天干天天插| 操碰91| 五月婷婷狠狠久久| 99热这里在线精品| 这里只有免费精品| 亚洲激情综合| 色婷婷aV四虎| 激情综合五月婷| 久久思思热视频| 日韩人妻无码专区| 久久久91精品| 99热最新网址| 99热这里只有精品免费观看| 日本色五月| 久久日曰| 五月丁香直播| 人人干99| 丁香婷婷综合色五月激情国产基地| 九九性视频| av性爱网站| 91狠狠色丁香婷婷综合久久| 另类视屏| 五月婷婷九| 欧美激情五月天婷婷| 九九九九这里只有精品| 色五月婷婷五月天| 国产精品色婷婷99久久精品| 天天热夜夜操| 婷婷五月天成人网| 久热亚洲| 狠狠色噜噜狠狠| 丁香五月电影| 九月影院義母在线播放| 色色综合色| 成人综合网站| 五月丁婷香| 91免费看片| 国产三级在线播放| 色五月天天| 激情綜合W W W,激情五月天| 亚洲无aV在线中文字幕| www一区二区三区| 99自拍视频在线观看| 9有码中文| 激情五月婷婷开心网| 99视频| 夜夜爽天天| 日本久久人人| 成人短视频在线免费观看| 亚洲经典小视频| 欧美成人AAA片一区国产精品| 丁香六月婷婷综合| 婷婷的色色五月天| 五月激情久久| av中文网站| 国产乱子轮XXX农村| 色色色色色色五月婷婷| 97色伦另类图片小说视频 | 色久影院| 亚洲精品大片| 色色97丁香婷婷五月天| 五月婷婷开心激情六月蜜桃| 色色国产| 黑人无码一区| 色婷婷综合网| 色99免费视频中文| 激情五月婷婷色播网| 天天碰夜夜操| 亚洲五月天天| 欧美性猛交AAAA片黑人 | 婷婷五月成年人| 可以直接看的AV| 久久99视频| www.五月天色色.com| 丁香五月电影院在线观看| 天天色亚洲| 国产免费av网站| 五月宗合激情网| 亚洲韩国日产综合AV| WWW.夜夜| 国产九月婷婷| www久热com| 五月丁香婷婷激情图片| 九九热在线99| 丁香五月婷婷久久久| 亚洲激情婷婷| 性爱五月婷婷| 亚洲性爱电影| 亚洲色碰| wwwss在线观看| 一区二区中文字幕| 久久九九综合| 色五月五月天| 狠狠狠狠草草| 韩国天天婷婷| 婷婷久久精品| 亚洲在线综合| 538午夜激情| 国产欧美日韩综合精品一区二区| 国产日日夜夜操| 影音先锋 萱萱| 国产Va视频| 日本色99网站| 五月天婷婷久久视频| 精品99视频| 色中色综合| 成人国产综合| 色婷婷久久| 五月天小说激情| 婷婷综合性爱网| 色五月丁香五月| 中美日韩成人在线| 激情婷婷丁香| 亚洲十月婷婷综合| 天天日日| 中文字幕综合| 婷婷五月天天| 婷婷五月丁香色色| 99riAV国产精品视频| 丁香午月AV中文字幕| 成人无码精品1区2区3区免费看| 天天插天天插天天插| 欧美操综合| 91丨九色丨东北熟女| 婷婷深爱五月亚洲综合| 色综合网页| 99热这里只有精品1025| 99热99成人| 男女啪啪视频久 9| 激情综合色图| 国产色色网址网站| 久久免费干| 狠狠高潮精品亚洲1| 中文精品在| 精品久久久91久久影视网| 另类小说激情五月天| 日韩婷婷| 第九色区AV在线| 九九综合色综合| 操逼福利视频| 婷婷五月中文字幕| 五月丁香亭亭| 久久怡红院| 永久99免费视频网站| 六月婷婷AV| 五月婷婷综合网| 九九热在线视频观看| 九九热99re8热免费观看| 欧美性猛交AAAA片黑人 | 婷婷射丁香| 秋霞三级色戒| 人人操大| 日本欧美成人片AAAA | 精品无码久久久久久久久| 激情五月婷婷五月| 欧美成人热| www.精品久9| 国产乱妇乱子在线播视频播放网站| 婷婷丁香人妻天天爽| 凹凸7777操操操| www.五月天色色色| 99精品偷自拍| 天天看A片| 亚洲狠狠干| 九九综合精品| 91干视频| 国产性爱在线| 超碰99在线观看| 人人射人人高潮| 丁香六月av| 九九色99| 天堂综合久| 久久婷婷五月综合色欧美| 日本色色色| h在线看免费版在线看| 色综合色欲综合天天免费| 婷婷天堂综合| 久久加勒比| 激情综合视频| 久久香蕉网| 激情综合亚洲| 久久激情网| 凹凸操Av| 人人性久久| 午夜福利8055| 亚洲av电影网站| 丁香五月天视频| 婷婷九月色| www999日韩精品| 五月婷婷 激情五月| 五月天四色房丁香| 欧美欧盟性爱网| 色五月婷婷影院| 亚洲视频1区| av操B网站| 四虎国产精品永久在线国在线| 99久久综合| 五月天婷婷爱| 色了色综合| 少妇久久诱惑视频| 99热大全在线观看| 婷婷五月av| 大香蕉婷婷色| 先锋资源91| 在线99色| 99热碰碰| 久久婷婷的综合色丁香五月| 亚洲中文字幕翔田千里| av中文字幕免费观看| 五月天丁香| 91日本在线观看| 丁香婷婷激情| 99热6精品| 开心激情网在线| 人人摸人人搞| 九九99精品视频在线观看| 中文字幕视频在线播放| 五月丁香六月成人| 婷婷在线视频| 久热AA| 国产欧美第五十五页| 婷婷五月色综合| 亚洲成人高清在线| 四色永久成人网站| 无码激情| 人人操AV| 色婷婷五月天| 风流少妇A片一区二区蜜桃| 亚洲精品久久久久久久久久飞鱼| 熟妇内谢69XXXXXA片| 五月丁香啪| 91精品激情9| 中文字幕成人版| 久久丁香综合精品综合| 五月丁香六月停停停| 亚洲无码免费看| 国产亚洲色婷婷久久99精品91 www.riverspirits.org www.hnnun.com www.changh | 五月丁香六月色婷婷综合五月天| 色婷婷婷av | 激情婷婷五月天在线观看| 天天插天天干天天舔| 思思热99在线视频| 精品久久99码| 综合网啪| 另类小说色婷婷| 少妇性BBB搡BBB爽爽爽视頻| 免费观看全黄做爰的视频| 91久女| 亚洲超级碰| 五月婷中文字幕| 5月婷婷视频网站综合| 精品99网站| 五月天成人在线播放丁香| 狠狠色综合精品视频在线| 91综合色| 色综合99| 99综合色色色| 九月婷婷综合网| 日本在线99| 成人看片网站| 精品99网站| 色无码| 成人片在线播放| 久久国产一区二区三区| 9 9热这里有精品| 色哟哟精品| 色五月丁香一区在线| 五月天激情无码| 婷综合| 91.www综合| 激情综合网色五月| 九九这里只有精品在线视频| 色操b| 色999;丁香五月| 狠狠干.com| 天堂成人久久| 亚洲熟妇AV综合网五月丁香伊人| 人人草人| 色情综合网| 91se精品国产| 超碰在线免费| 男人综合网| 97色在线观看视频| 人妻丰满精品一区二区A片| 啪啪操网| 777色婷婷爱五月| 深情五月天| 久久99精品视频| 久久婷婷五月丁香蜜桃网| 日本人人干| 丁香五月色播中文在线播放| 综合激情五月天六月婷免费视频| 五月丁香啪啪综合| 超碰99成人在线| 色性综合| 日日操日日撸| av亚洲国产小电影| 国产精品视频免费看| 五月花成人网| 五月婷婷狠狠干| 4399无码视频二区| 五月丁香综合| 六月天婷婷| 97精品人人A片免费看| 奇米四色五月天| 色小说婷婷五月天天天| 日韩色五月| 亚洲一二三网| 丁香五月激情六月欧亚激情综合导航| 九九热视频精品| www.色五月| 日本三级中文字幕| 激情开心五月天婷婷基地丁香社区| 婷婷五月天av| 丁香婷色| 丁香五月婷在线观看| 1000部毛片A片免费观看| 99热这里都是精品| 色天天综合| 三人荫蒂添的好舒服A片| 六月婷婷综合| 97五月天| 牛牛澡牛牛爽| 丁香五月婷婷久久久| 97碰| 丁香婷婷婷婷十二月在线观看视频| 婷婷五月色影视先锋| 五月天婷婷激情小说电影| 九九综舍久久| 色丁香影院| 婷婷五月花.97| 六月色色综合| 成人视频在线免费播放| 波多婷婷久久| 九九热在线视频,| 亚洲乱码精品久久久久..| 99在线观看视频| 噜噜噜久久| 日韩无码91| 淑女丝袜bi操逼123| 亚洲第一成人无码A片| 激情深爱婷婷网| 99热九九热| 91精品久久久久久77777| 色五月av| 九九精品99久久久| 色色色无码| 大鸡巴伊人网| 丁香五月中文字幕久色| 91丁香色| 色狠狠色狠狠| 亚洲春色奇米影视| 内射丰满人妻| 欧美成人AAA片一区国产精品| 再次出发二| 99热这里全都是精品| 性色人人爽| 久久丁香五月天| 久久99这里只有精品| 伦乱天堂| 色综合丁香| 五月激情六月综合| 精品婷婷五| 丁香五月在线播放| 色婷婷五月六月丁香综合视频| 五月婷在线| 激情丁香淫荡婷婷| 激情五月综合| 久久婷婷五月综合激情国产| 国产精产国品一二三在观看| 99操99| 99久在线精品99re8| 天堂婷婷五月在线| 男女啪啪做爰高潮无遮挡| 色婷婷亚洲| 婷婷伊人网| 婷婷五月天另类视频| 欧美性生交XXXXX无码小说| 五月婷婷激情性爱| 无码动漫av| 欧洲不卡视频| 色无码| 欧美五月丁香啪啪响视频| 亚洲人妻av| 99爱免费在线视频| 九 九九九AV| 26uuu另类亚洲欧美日本一| 色色网91| 成人网站免费在线播放| 99综合免费视频| 五月丁香六月色| 丁香婷婷五月综合色情| 日本颜色视频人人爱| 日韩99视频| 99热这里全都是精品| 婷婷5月开心6月| 在线成人国产| 五月天激情网站| 大香蕉手机视频| 欧洲MV日韩MV国产| 六月丁香六月婷婷欧美| 开心五月深爱五月丁香五月激情五月 | 丁香 婷婷 亚洲 熟女| 伊人成综合五月婷婷| 久久五月激情综合| 久久五月天综合视频网站| 青青草大香| 女高怪谈在线观看| 大香蕉啪啪| 国产AV一区二区三区最新精品| 婷婷五月天堂一本在线| 97碰碰草| 日本99在线视频| 激情婷婷亚洲五月| 九九激情视频| 婷香五月激情视频| 丁香花五月天| 国产AV不卡福利| 激情小说五月天| 五月丁香黄色视频| 91超级碰在线视频| 欧美日韩欧美| 天天日夜夜曹| 91婷婷| 91婷婷搞| 激情综合网亚洲色图| 久久免费丁香| 三年高清大片免费观看国语| 天天操夜夜操| 久草久青福利| 人人操大| 国产亚洲精品AAAA片APP|