:用ModScan32和Wireshark拆解報文定位問題)
搞Modbus協(xié)議開發(fā)的朋友應該都有過這種經歷明明從站設備就在那兒上位機軟件也能連上但讀寫寄存器就是不對——數(shù)據(jù)讀出來全0、寫參數(shù)設備沒反應、偶發(fā)超時、真機上調得好好的程序到了現(xiàn)場亂跳。這時候光靠ModScan32去看“結果”很難定位到底是在哪一層出了問題。把Wireshark拉進來把報文從鏈路層到應用層全部拆開看才能找到真正的根因。這篇是系列的第二篇上一篇已經把ModScan32的基本使用和Wireshark的基礎過濾講過了這次直接進入正題用ModScan32做操作、Wireshark做旁路抓包把Modbus TCP的每一幀報文從十六進制到業(yè)務字段全部讀懂再把調試中常見的數(shù)據(jù)錯亂、地址偏移、功能碼不匹配等問題逐一拆透。1. 工作臺上的組合為什么是 ModScan32 加 Wireshark1.1 ModScan32 到底解決什么問題ModScan32在Modbus開發(fā)里的地位有點像是萬用表在電路維修里的地位。它本身是個主站模擬工具能主動發(fā)起Modbus請求往從站設備或模擬器上讀寫線圈、離散輸入、保持寄存器、輸入寄存器。你不需要寫一行代碼直接在界面上指定IP、端口、功能碼、起始地址、數(shù)據(jù)長度它就能把請求發(fā)出去并且把返回的數(shù)據(jù)按你指定的格式顯示出來。但它的能力邊界也在這它能告訴你“讀到了什么”幾乎不告訴你“讀的過程發(fā)生了什么”。舉個例子一臺儀表的保持寄存器地址是40001到40010你用ModScan32填起始地址1去讀結果數(shù)據(jù)全是0。你換了起始地址0數(shù)據(jù)就出來了。這時候ModScan32顯示得很正常甚至你都沒覺得有問題。但如果現(xiàn)場同事問一句“為什么地址1讀不到”你就得從協(xié)議的角度解釋清楚這一步恰恰需要看報文。1.2 Wireshark 在 Modbus 調試里的角色Wireshark解決的是“過程可見”的問題。它能把每個TCP幀的完整字節(jié)抓下來然后根據(jù)Modbus協(xié)議規(guī)范幫你解析出MBAP頭、功能碼、寄存器地址、數(shù)據(jù)值甚至把異常響應里的異常碼都翻譯成人話。調試的時候我一般是讓ModScan32保持輪詢Wireshark在旁邊一直抓包等數(shù)據(jù)不對時直接停下來看最后一個請求和對應的響應幾秒鐘就能定位問題在哪一端。尤其遇到設備廠商的從站固件行為比較特殊的情況只有Wireshark能告訴你真相。比如某個從站對不支持的地址返回了“非法數(shù)據(jù)地址”異常碼02但ModScan32界面上可能只會顯示一個問號或者干脆空白你不會知道是請求本身發(fā)錯了還是從站拒絕了你。而在Wireshark里異常的響應幀一眼就能看到功能碼變成了0x83后面跟著02問題邊界立刻清晰。1.3 這套組合適合哪些場景我自己的經驗里這幾個場景用這套組合最值回票價第一新接入一款不熟悉的從站設備要快速確認寄存器映射、字節(jié)序、支持的功能碼第二寫上位機程序之前用ModScan32和模擬從站先把協(xié)議鏈路驗證一遍排除設備端問題第三程序寫完聯(lián)調時遇到超時、地址對不上、數(shù)據(jù)錯誤用Wireshark抓包看請求是否按預期組裝第四排查非本機通信的場景比如中間經過路由器、網(wǎng)關或者串口服務器只要數(shù)據(jù)沒按預期跑通抓包就能判斷數(shù)據(jù)是在哪一段被改壞或丟棄的。這套組合能覆蓋從協(xié)議驗證、設備摸底到程序聯(lián)調的大部分環(huán)節(jié)。后面所有章節(jié)都會圍繞這個組合展開咱們先把手上的工具準備齊。2. 環(huán)境準備與會話搭建2.1 常用軟件選型和模擬從站準備做Modbus TCP調試環(huán)境里至少要有三樣東西主站工具ModScan32、抓包工具Wireshark、一個能響應Modbus請求的從站。從站可以是真實設備但開發(fā)階段我更推薦先用手頭的模擬從站軟件把鏈路打通再拿到真機上驗證。模擬從站的好處是可控——寄存器值隨便改支持的功能碼隨便配甚至能故意制造異常響應來測試主站的健壯性。市面上常見的從站模擬工具有不少Modbus Slave這類工具用起來比較直觀能配置多個寄存器區(qū)還能模擬異常。如果只是臨時起一個簡單的從站一些開源的工具也能跑。選型的標準是能看到收到什么請求、能手動修改寄存器值、能配置Unit ID。別小看這三點實際排查問題時你會發(fā)現(xiàn)“從站到底有沒有收到請求”和“從站回了什么內容”比什么都重要。Wireshark的安裝有一點要特別提醒抓回環(huán)流量時需要Npcap支持。如果你裝Wireshark時用的是老版本W(wǎng)inPcap可能在回環(huán)網(wǎng)卡上抓不到包建議把抓包組件更新到Npcap版本并且在安裝時勾選“Support loopback traffic”。這一步沒做好后面ModScan32和模擬從站跑在同一臺電腦上時你會什么都抓不到白折騰半天。2.2 通過 ModScan32 快速建立與從站的通信啟動ModScan32之后首要任務是建立連接。在界面的連接區(qū)域選擇Modbus TCP/IP類型Server地址填從站的IP如果從站就在本機就填127.0.0.1端口默認502。如果你的從站配置了多個Unit ID要在Device ID欄里填對否則請求會被從站直接忽略或返回異常。連接建立后ModScan32默認會按某個功能碼周期輪詢。我第一次用它時犯過一個低級錯誤沒注意默認的輪詢功能碼是FC01讀線圈結果連上一個只支持保持寄存器的設備界面上滿屏的讀取失敗提示。后來養(yǎng)成習慣每次新建連接后第一件事就是檢查Function下拉框把它切到目標功能碼比如讀保持寄存器就選FC03讀輸入寄存器選FC04。地址和長度的設置也要說清楚。ModScan32界面上的Address通常顯示的是數(shù)據(jù)地址0起始而很多設備手冊里寫的是寄存器編號比如“40001對應協(xié)議地址0x0000”。這兩者差1非常容易搞混。我的經驗是拿到設備手冊先看它有沒有單獨給出一張“協(xié)議地址映射表”如果有你就按照協(xié)議地址填如果只給了寄存器編號那就要在編號基礎上減1再填進ModScan32。2.3 用 Wireshark 開始抓包過濾、啟動、同步時間打開Wireshark之后先選對網(wǎng)卡。ModScan32連的是本機從站時要選回環(huán)接口名稱一般是“Loopback: lo”或“Npcap Loopback Adapter For Loopback Traffic Capture”。如果連的是局域網(wǎng)里的真實設備就選對應的物理網(wǎng)卡。網(wǎng)卡選錯是新手期最常見的問題我看到過有人抓了一晚上只看到自己電腦的廣播包設備報文一個都沒抓到原因是電腦上有好幾塊網(wǎng)卡設備接在另一塊上。抓包啟動后立刻在過濾欄輸入tcp.port 502這樣只顯示Modbus TCP流量不會被其它噪聲干擾。如果你想更精確一點可以再加上對端IPip.addr 192.168.1.100 tcp.port 502。啟動抓包的同時讓ModScan32開始輪詢或手動觸發(fā)一次讀寫Wireshark這邊就能看到成對的請求和響應幀了。這里還有一個細節(jié)值得養(yǎng)成習慣在Wireshark的View菜單里把時間顯示格式改成“Seconds Since Previous Displayed Frame”或者“Seconds Since First Frame”。Modbus TCP調試經常需要看響應時間默認的絕對時間在判斷超時問題時不夠直觀。相對時間一眼就能看出從請求發(fā)出到響應返回隔了多少毫秒這對排查偶發(fā)性超時問題幫助很大。3. 第一次抓包從 ModScan32 到 Wireshark 的數(shù)據(jù)流3.1 讀保持寄存器FC03的完整報文拆解假設你在ModScan32里設置功能碼FC03起始地址0長度10個寄存器并且讓模擬從站把這些寄存器的值設置成已知的數(shù)。點擊讀取之后Wireshark里會先出現(xiàn)一條從主站發(fā)往502端口的請求幀。展開這條TCP報文的應用層負載默認情況下Wireshark已經幫你解析成了Modbus協(xié)議字段。先看請求部分的字節(jié)構成一個典型的FC03請求是這樣12個字節(jié)的十六進制數(shù)據(jù)00 01 00 00 00 06 01 03 00 00 00 0A逐段拆開看前兩個字節(jié)00 01是事務處理標識符用于關聯(lián)請求和響應接著00 00是協(xié)議標識符Modbus協(xié)議規(guī)定這個字段為0再接著00 06是后續(xù)字節(jié)的長度它表示從單元標識符到數(shù)據(jù)末尾一共6個字節(jié)然后是01單元標識符再往后的03是功能碼表示“讀保持寄存器”00 00是起始寄存器地址00 0A是寄存器數(shù)量十進制就是10。再看響應正常情況下是這樣一組字節(jié)00 01 00 00 00 17 01 03 14 C0 A1 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F和請求對應事務標識符00 01和請求相同說明這是那一次請求的響應。00 00協(xié)議標識符不變00 17是長度十進制23代表從單元ID開始有23個字節(jié)。01單元ID、03功能碼都和請求一致緊接著的14是數(shù)據(jù)字節(jié)數(shù)十進制20表示后面跟著20個字節(jié)的寄存器值每個寄存器2個字節(jié)正好對應請求里10個寄存器的長度。我第一次把這兩幀放在一起看的時候整個Modbus協(xié)議一下子“通”了。所謂通訊協(xié)議本質上就是對字節(jié)的約定你按約定發(fā)出請求對方按約定回數(shù)據(jù)。Wireshark把這些約定翻譯成了人話但你如果能自己看懂原始十六進制就能脫離Wireshark自帶的解析器直接判斷是不是解析器本身識別錯誤的問題。3.2 寫多寄存器FC16的完整報文拆解讀操作只是請求響應兩個半場寫多寄存器FC16則會涉及更長的數(shù)據(jù)段。假設要通過ModScan32往從站地址0和1寫入兩個寄存器的值設置數(shù)據(jù)分別為0x1234和0xABCD抓包會看到這樣一幀請求00 02 00 00 00 0B 01 10 00 00 00 02 04 12 34 AB CD對照解析00 02是事務ID00 00協(xié)議ID00 0B長度十進制11表示從單元ID起有11個字節(jié)01單元ID10就是十進制16即FC16寫多寄存器。00 00起始地址00 02要寫的寄存器數(shù)量04表示后面數(shù)據(jù)總字節(jié)數(shù)最后12 34 AB CD就是按順序寫入兩個寄存器的值。對應響應幀通常是00 02 00 00 00 06 01 10 00 00 00 02注意FC16的正常響應不回寫數(shù)據(jù)內容它只回顯起始地址和寄存器數(shù)量告訴主站“我寫成功了”。如果從站返回的功能碼變成了0x90即10 | 0x80那就說明這是一條異常響應后面跟的異常碼會解釋拒絕原因。這個設計在R/W調試時特別值得記住不要指望寫操作響應里帶回你剛寫入的數(shù)據(jù)想看寫沒寫對要么再發(fā)一次讀請求要么就在從站那邊確認。3.3 單線圈操作FC05的寫值細節(jié)單線圈寫操作FC05和寄存器寫操作有一個容易栽跟頭的區(qū)別寫線圈時Open和Close對應的不是0和1而是0xFF00和0x0000。某個從站如果對寫入值的檢查很嚴格你發(fā)00 01它可能不認只有完整的0xFF00它才認為是“置位”。ModScan32在界面上做單線圈寫的時候通常只是勾選一個復選框你根本不會去關心底層字節(jié)。但在分析Wireshark抓包時如果看到某條FC05請求的數(shù)據(jù)段是兩個字節(jié)的FF 00不要覺得奇怪這是Modbus協(xié)議定義的標準寫法。而且FC05的響應是請求的完整回顯功能碼、地址、值全部原樣返回說明沒有異常。從抓包驗證的角度你甚至可以把響應和請求逐字節(jié)比對確認從站確實收到了正確內容。從這個層面說ModScan32幫你生成了合規(guī)的請求幀而Wireshark幫你確認了請求幀在網(wǎng)絡上是什么樣子。二者配合起來你就能逐步建立“界面操作—字節(jié)轉換—協(xié)議語義”三者之間的對應關系這比背協(xié)議文檔有效得多。4. 深層報文分析從字節(jié)里讀出問題4.1 MBAP 頭部與協(xié)議字段含義Modbus TCP的應用層數(shù)據(jù)分為兩個部分前面7個字節(jié)是MBAP頭Modbus Application Protocol Header后面是PDU協(xié)議數(shù)據(jù)單元。MBAP頭的存在是Modbus TCP相比Modbus RTU最大的區(qū)別。RTU有地址域和CRC校驗TCP則用MBAP頭來替代因為TCP和IP層已經解決了尋址和校驗的問題。MBAP頭的7個字節(jié)我習慣按四個字段記Transaction Identifier事務ID2字節(jié)用來把請求和響應配對Protocol Identifier協(xié)議ID2字節(jié)在標準Modbus里恒為0Length長度2字節(jié)表示它后面所有字節(jié)的數(shù)量即Unit ID加PDU的總長Unit ID單元標識1字節(jié)用來標識設備號在TCP直接連接一臺從站時一般填1但經過網(wǎng)關轉換再下掛串口設備時這里的意義就變成了鏈路后方的設備地址。事務ID這個字段在調試高并發(fā)上位機時值得多留意。如果你的上位機用多線程同時發(fā)請求然后靠“先收到的響應就丟給當前等待的線程”那事務ID就完全對不上數(shù)據(jù)全亂。正確做法是每個請求分配一個事務ID響應回來時按事務ID匹配。Wireshark的Modbus解析器非常貼心它會直接顯示請求和響應的Transaction ID是否一致你能很直觀地看出亂七八糟的響應到底對應哪個請求。4.2 PDU 中功能碼和數(shù)據(jù)字段詳解PDU的結構比MBAP更簡潔功能碼一個字節(jié)后面跟著數(shù)據(jù)。功能碼決定了整個PDU的語義和格式。0x01讀線圈、0x02讀離散輸入、0x03讀保持寄存器、0x04讀輸入寄存器、0x05寫單線圈、0x06寫單寄存器、0x0F寫多線圈、0x10寫多寄存器。還有0x17讀/寫多寄存器等組合操作但在儀表、傳感器類設備里出鏡率沒那么高。異常響應是PDU里一個需要特別熟悉的形式。當從站無法處理請求時它會把功能碼的最高位置1比如FC03變成0x83FC16變成0x90然后數(shù)據(jù)段第一個字節(jié)就是異常碼。異常碼各有含義01是非法功能說明從站根本不支持這個功能碼02是非法數(shù)據(jù)地址說明地址超范圍或不存在03是非法數(shù)據(jù)值說明數(shù)據(jù)本身不合法比如寫線圈時寫了0x0001而不是0xFF0004是從站設備故障設備內部異常06是從站忙稍后再試。實際調試中異常的判斷價值很大。假設你向一臺只支持FC03和FC04的設備發(fā)FC06寫單個寄存器Wireshark里會看到請求正常發(fā)出響應卻返回0x86和異常碼01。你立刻就能知道是這個功能碼不被支持而不是地址或數(shù)據(jù)值的問題。如果沒有Wireshark你可能會在ModScan32界面上反復調整寄存器地址怎么試都不成功白白浪費時間。4.3 字節(jié)序、寄存器映射與地址偏移的坑字節(jié)序是Modbus調試里最經典的坑之一。Modbus協(xié)議本身規(guī)定寄存器數(shù)據(jù)按大端傳輸即高字節(jié)在前、低字節(jié)在后。比如寄存器值0x1234在網(wǎng)絡上先傳0x12再傳0x34。這本身沒有歧義但問題出在當寄存器數(shù)據(jù)被轉換到16位以上的數(shù)值時——比如32位浮點數(shù)、32位整數(shù)不同廠家對“兩個字寄存器在內存里的排列順序”的理解不一樣。我一個實際項目里遇到過這樣的情況某設備的32位浮點參數(shù)在設備說明書里標著“使用兩個連續(xù)保持寄存器”但沒有寫字節(jié)序。ModScan32讀回來后按默認的“前寄存器存高16位”格式顯示數(shù)值完全不對。我試著把顯示格式切到“前寄存器存低16位”數(shù)值瞬間變成合理的工程量。而這在Wireshark里看原始字節(jié)是完全一樣的區(qū)別只在于你如何解釋這兩個寄存器。所以判斷字節(jié)序唯一可靠的方法是先把一個已知值寫入從站再用Wireshark看原始字節(jié)然后結合你想要的數(shù)值反推排列方式。別信廠家的含糊敘述也先別急著改代碼先用工具把字節(jié)序摸清楚后面寫上位機時直接在協(xié)議層做字節(jié)交換就行。另一個同樣坑的是地址偏移。很多設備的“寄存器號”從1開始編號比如40001、40002而協(xié)議報文里的地址從0開始。ModScan32界面上填1和填0會讓請求里的地址字段差一個。我用Wireshark看過一個實際案例工程師在ModScan32里填了地址40001界面提示“地址無效”他改填40000才成功。但抓包一看報文里的地址字段其實一直是0x9C41因為界面上顯示的地址和線纜上的地址根本是兩套編碼方式。讀協(xié)議文檔時一定要看它給的是“Modbus地址”還是“寄存器編號”這兩個差一分請求就偏離一分。5. 調試中常見的異常與排查5.1 連接建立但數(shù)據(jù)不對優(yōu)先檢查功能碼、地址和長度現(xiàn)象是ModScan32能連上從站但讀到的寄存器要么全0要么是明顯不可能出現(xiàn)的值。這時候別急著懷疑設備壞了先回看Wireshark里的請求幀依次核對三個要素功能碼是否對應你要讀的區(qū)域、起始地址是否落在設備支持的范圍內、長度是否跨出了有效區(qū)。舉個例子有的設備保持寄存器地址范圍是0到49總共50個寄存器。你在ModScan32里填了起始地址48長度10那么實際請求會要求讀地址48到57后面8個地址超出了設備范圍。多數(shù)從站會返回異常碼02但也有一些實現(xiàn)不完善的從站直接回一個“能讀多少讀多少”的截斷響應甚至返回全0。遇到這種情況抓包能立即看到問題出在請求組裝的越界上不是你程序里的錯。如果功能碼和地址看起來都對數(shù)據(jù)依然不對那就要考慮數(shù)據(jù)類型解釋的問題。ModScan32界面上有數(shù)據(jù)格式選項可以把數(shù)據(jù)顯示成十六進制、十進制、浮點等。不要直接在十進制顯示下判斷“數(shù)值不對”先切到十六進制看原始寄存器值再結合設備手冊理解每個位和字節(jié)的含義。5.2 從站有響應但界面空白檢查異常幀還有一種情況比較隱蔽ModScan32界面上某個地址格子里一直空白好像從站沒響應。但Wireshark明明抓到了響應幀而且響應里帶著功能碼和異常碼。為什么ModScan32不顯示異常信息因為它的顯示區(qū)設計比較簡單有些異常它只會把這個格子的數(shù)據(jù)置為無效不會彈一個窗口告訴你“這次請求被從站拒絕了”。所以當你發(fā)現(xiàn)ModScan32某些格子讀不到數(shù)據(jù)時立刻按CtrlF在Wireshark里過濾modbus.func_code 0x80把所有異常響應一次性列出來。異常碼會直接告訴你從站拒絕請求的原因。這里我想強調一下“非法數(shù)據(jù)地址”和“非法功能”的區(qū)別如果請求的功能碼本身不在從站支持列表里回的是01如果功能碼支持但地址超范圍回的是02。這兩個信息對應的排查方向完全不同別混在一起。還有一點ModScan32的輪詢速度可能很快從站如果因為忙沒來得及處理會回異常碼06。這種情況Wireshark里能看到響應時間很短但帶異常說明是從站太慢。遇到這類從站ModScan32的輪詢間隔就要調大一些否則正常的寄存器讀寫也可能被誤判為通信失敗。5.3 Wireshark 看不到 Modbus 解析端口和字節(jié)問題Wireshark不能自動識別Modbus協(xié)議通常是這幾個原因。最普遍的是端口不是502。Modbus TCP規(guī)范默認跑在TCP 502端口Wireshark的解析器默認也認這個端口。如果你的上位機、網(wǎng)關或測試工具用了別的端口比如5020Wireshark就不會把它當Modbus顯示只會看到一個TCP負載。解決辦法有兩種一是在過濾欄里等TCP流建立后右鍵任意一條TCP報文選擇“Decode As”把該端口或該TCP流的協(xié)議強制設為Modbus TCP二是讓服務端保持用502端口客戶端可以隨便只要抓包時Decode As設置好就能解決。另一種情況是數(shù)據(jù)被拆分或合并。TCP是流式傳輸不是消息邊界分明的UDP。一個Modbus請求雖然只有十幾個字節(jié)但可能被TCP層拆成兩個段發(fā)送也可能兩個小請求被合并到一個段里。Wireshark的Modbus解析器處理這種情況時如果只是設置了Decode As會有概率解析不出來。這時候可以右鍵第一條報文選擇“Follow TCP Stream”在流內容里肉眼找MBAP頭的特征字節(jié)比如協(xié)議ID00 00和長度字段手動判斷應用層的邊界。如果連原始字節(jié)都看不到那問題就出在抓包的位置或網(wǎng)卡上。我記得前面反復強調過回環(huán)網(wǎng)卡這個問題真機調試時還會遇到交換機鏡像、無線抓包等更復雜的環(huán)節(jié)但基本排查思路是一致的要么離設備更近要么確認鏈路中間沒有把包改寫。5.4 響應超時和重試問題先看時間戳再下結論Modbus TCP的超時問題通常有兩種表象ModScan32提示通信超時或者上位機頻繁報超時。這時候Wireshark里看時間戳最有說服力。請求發(fā)出后如果過了很長時間才收到響應那就是從站處理慢或者網(wǎng)絡鏈路質量差如果壓根沒看到響應那就是請求根本沒到達從站或從站的響應沒回來。判斷這個有個小技巧打開Wireshark的“Statistics - Flow Graph”功能選擇顯示TCP流。界面里會按時間軸列出每個段的發(fā)送方向、相對時間。第一次看到這種圖時你會非常直觀地感受到“原來響應等了這么久”或者“原來重試風暴是先請求超時后立刻重發(fā)積壓出來的”。在排查程序里的超時重試邏輯時我經??窟@個視圖確認重試間隔設置得是否合理。另外要留意TCP層的重傳。如果Wireshark里出現(xiàn)大量TCP Retransmission說明鏈路丟包比較嚴重此時Modbus應用層的超時只是表象真正要修的是網(wǎng)絡質量或者TCP參數(shù)。這個思路可以避免你陷入無休止地調Modbus超時時間的死循環(huán)。6. 實戰(zhàn)心得與建議6.1 關于輪詢周期和流量控制的取舍ModScan32的輪詢間隔最小能設到很低但現(xiàn)實是遠程設備或網(wǎng)關經不起你這么快的輪詢。有些串口服務器把Modbus TCP轉成RTU時串口波特率只有9600一個帶有10個寄存器的讀請求加上等待時間至少要幾十毫秒。如果你上位機上用ModScan32測試時把輪詢設得飛快看起來沒問題等到現(xiàn)場大量真實請求并發(fā)時就容易撞車。抓包時你會觀察到連續(xù)的Modbus TCP請求經常出現(xiàn)包被合并的現(xiàn)象這就是TCP層Nagle算法和延遲確認在起作用。短請求多的情況下這種合并會降低應用層的實時性。如果上位機程序對響應時間敏感可以考慮在TCP層關閉Nagle算法但ModScan32本身沒有這個開關所以你只能在抓包分析時把它當成一個“為什么會慢”的解釋維度。6.2 真實設備場景下抓包的一點經驗真機調試和模擬器最大的區(qū)別是你不再擁有對從站內存和行為的完全控制。真實設備可能掛在現(xiàn)場總線上上游還有PLC、網(wǎng)關、觸摸屏同時訪問它。這時候用Wireshark抓包要注意過濾條件不要只寫tcp.port 502最好加上目標設備的IP或者網(wǎng)關的IP否則同一網(wǎng)絡上其它Modbus設備的數(shù)據(jù)會把你的分析淹沒。如果你在電腦上直接連設備抓到的包實際上經過了你的網(wǎng)卡和交換機能看到的內容取決于抓包點的位置。能抓到主站發(fā)出的請求、但看不到從站響應通常說明從站響應被交換機某個端口隔離了兩邊都能看到但內容不一致那就要考慮鏡像口配置或者中間網(wǎng)關的透明轉發(fā)問題。抓包分析很像照CT你得知道自己在哪個層面看才能判斷影像是真實的還是誤差的。6.3 一點個人體會用ModScan32加Wireshark這套組合已經好幾年最大的體會是協(xié)議調試難往往不是難在對協(xié)議不熟而是難在“信息太少”和“信息太多”兩個極端之間。沒有Wireshark時你只有一個黑盒界面出了問題只能靠猜有了Wireshark你又會面對成百上千幀報文如果不會篩選和拆解反而更容易迷失。務實的做法是先控制變量把請求限制成固定IP、固定功能碼、少量寄存器讓人和機器都能看清一個完整的交互再逐漸往復雜場景擴展。我在實際調試設備時有一個固定的流程至今沒有變過先用自己的主站工具讀一次Wireshark看一次原始請求再用從站手冊里的標準報文手工構造一個請求主動發(fā)到設備上看它的響應最后才編寫上位機代碼。三步走下來十個問題里能提前規(guī)避九個。剩下一個偶發(fā)問題大概率是現(xiàn)場網(wǎng)絡環(huán)境的干擾那時候帶上Wireshark到現(xiàn)場再看一次也能順利定位。最后再分享一個小技巧如果你在ModScan32和現(xiàn)場設備之間串了一臺電腦做透明轉發(fā)可以用它做“雙頭抓包”對比分析一頭看主站發(fā)的、一頭看設備收的。兩邊報文不一致問題肯定在中間。配合Wireshark的導出報文功能把對比結果保存下來回頭發(fā)給協(xié)議?;蛘呔W(wǎng)關廠商他們也能很快明白問題所在。這套方法幫我省下過很多次現(xiàn)場返工的時間也希望能在你的項目里幫上忙。