Modbus協議的相關知識


Modbus協議的相關知識

協議概要

簡而言之,Modbus協議是一種單主/多從的通訊協議,其特點是在同一時間總線上只能有一個主設備,但可以有一個或者多個(最多247個)從設備。Modbus通信總是由主設備發起,當從設備沒有收到來自主設備的請求時,不會主動發送數據。從設備之間不能相互通信,主設備同時只能啟動一個Modbus訪問事務處理。

主設備可以采用兩種方式向從設備發送Modbus請求報文,即主設備可以對指定的單個從設備或者線路上所有的從設備發送請求報文,而從設備只能被動接收請求報文后給出響應報文即應答。

  • 單薄模式:主設備僅僅尋址單個從設備。從設備接收並處理完請求之后,向主設備返回一個響應報文,即應答。在這種模式下,一個Modbus事務處理包含兩個報文:一個是主設備的請求報文,一個是從設備的響應報文。

每個從設備必須有唯一的地址(地址范圍1~247),這樣才能區別於其他從設備從而可以獨立被尋址,而主設備不占用地址。

  • 廣播模式:此種模式下,主設備可以向所有的從設備發送請求指令。而從設備在接收到廣播指令后,僅僅進行相關指令的事務處理而不要求返回應答·基於此,請求指令必須是Modbus標准功能中的寫指令。

根據Modbus標准協議的要求,所有從設備必須接收廣播模式下的寫指令,且地址0被保留用來識別廣播通信。

請求

主設備發送的請求報文主要包括從設備地址(或者廣播地址0)、功能碼、傳輸的數據以及差錯檢驗字段。

查詢消息中的功能碼告知被選中的從設備要執行何種功能。數據段包含了從設備要執行功能的任何附加信息。例如功能代碼03元哦求從設備讀保持寄存器並返回其內容。

數據段必須包含要告知從設備的信息:從何寄存器開始讀取及要讀取的寄存器數量。差錯檢測域為從設備提供了一種驗證消息內容是否正確的方法。

應答

從設備的應答報文包括地址、功能碼、差錯檢測域等。

如果從設備產生一個正常的回應,則在回應消息中的功能碼是在查詢消息中的功能碼的回應。數據段包括了從設備手機的數據,如寄存器值或狀態。如果有錯誤發生,功能代碼將被修改以用於指出回應消息是錯誤的,同時數據段包含了描述此錯誤信息的代碼。差錯檢測域允許主設備確認消息內容是否可用。

對於串行鏈路來說,又存在兩種傳輸幀模式ASCII模式和RTU模式。但是對於同一網絡或鏈路來說,所有的設備必須保持同一,要么統一為ASCII模式,要么同一為RTU模式,不可共存。相對來說,RTU模式傳輸效率更高,因此,在當前普通的生產環境中RTU模式獲得了廣泛應用,而ASCII模式只作為特殊情況下的可選項。

Modbus寄存器

寄存器種類說明

Modbus協議中一個重要的概念是寄存器,所有的數據均存放於寄存器中。Modbus寄存器更具存放的數據類型以及各自讀寫特性,將寄存器分為4個部分,這4個部分可以連續也可以不連續,由開發者決定。寄存器的意義如下:

寄存器種類 說明 與PLC類比 舉例說明
線圈狀態
(Coil Status)
輸出端口
可設定端口的輸出狀態,也可以讀取該位的輸出狀態。可分為兩種不同的執行狀態,例如保持型或邊緣觸發型
DO(數字量輸出) 電磁閥輸出,MOSFET輸出、LED顯示等
離散輸入狀態
(Input Status)
輸入端口
通過外部設定改變輸入狀態,可讀但不可寫
DI(數字量輸入) 撥碼開關、接近開關等
保持寄存器
(Holding Register)
輸出參數或保持參數,控制器運行時被設定的某些參數,可讀可寫 AO(模擬量輸出) 模擬量輸出設定值,PID運行參數,變量閥輸出大小,傳感器報警上限
輸入寄存器
(Input Register)
輸入參數
控制器運行時從外部設備獲得的參數,可讀但不可寫
AI(模擬量輸入) 模擬量輸入

寄存器地址分配

Modbus寄存器地址分配如下:

寄存器種類 寄存器PLC地址 寄存器Modbus協議地址 簡稱 讀寫狀態
線圈狀態 00001~09999 0000H~FFFFFH 0x 可讀可寫
離散輸入狀態 10001~19999 0000H~FFFFH 1x 只讀
保持寄存器 40001~49999 0000H~FFFFH 4x 可讀可寫
輸入寄存器 30001~39999 0000H~FFFFH 3x 只讀

該表中的PLC地址可以理解為Modbus協議地址的變種,在觸摸屏和PLC編程中應用較為廣泛。寄存器PLC地址指存放於控制器中的地址,這些控制器可以是PLC,也可以是觸摸屏、或是文本顯示器。PLC地址一般采用10進制描述,共有5位,其中第一位數字代表寄存器類型。第一位數字和寄存器類型的對應關系表3-2所示。例如,PLC地址40001、30002等。

寄存器Modbus協議地址指的是通信時使用的寄存器尋址地址,例如PLC地址40001對應尋址地址時0x0000,40002對應地址0x0001,寄存器尋址地址一般使用16進制描述。再如,PLC寄存器地址40003對應的協議地址時0x0002,PLC寄存器地址30003對應的協議地址也是0x0002,雖然兩個PLC寄存器通信時使用相同的Modbus協議地址,但是因為不同寄存器的功能碼不同,需要使用不同的命令訪問,所以訪問時不存在沖突。

Modbus 串行消息幀格式

Modbus ASCII或RTU模式僅適用於標准的Modbus協議串行網絡,它定義了在這些網絡上連續傳輸的消息段的每一個字節,以及決定怎樣將消息打包成消息域或如何解碼等功能。

ASCII消息楨格式

當控制器設為在Modbus網絡上以ASCII模式通信時,在消息中每個8位(bit)的字節都將作為兩個ASCII字符發送。這種方式的主要優點是字符發送的時間間隔可達到1秒而不產生錯誤。

在ASCII模式下,消息以冒號(:)字符(ASCII碼0x3A)開始,以回車換行符結束(ASCII碼0x0D,0x0A)消息幀的其他字段(域)可以使用的傳輸字符是十六進制的0·····9,A·····F。處於網絡上的Modbus設備不斷偵測“:”字符,當有一個冒號接收到時,每個設備進入解碼階段,並解碼下一個字段(地址域)來判斷是否是發給自己的。消息楨中的字符間發送的時間間隔最長不能超過1秒,否則接收的設備將認為發生傳輸錯誤。

一個典型的ASCII消息幀格式如下:

起始 地址 功能碼 數據 LRC校驗 結束
1字符
2字符 2字符 0~2*252字符 2字符 2字符
CR,LF

RTU消息幀格式

傳輸設備(主/從設備)將Modbus報文放置在帶有已知起始和結束點的消息中,這就要求接收消息幀的設備在報文的起始處開始接收,並且要知道報文傳輸合適結束。兩外還必須能夠檢測到不完整的報文,且能夠清晰地設置錯誤標志。

在RTU模式中,消息的發送和接收以至少3.5字符時間的停頓間隔為標志。實際使用中,網絡設備不斷偵測網絡總線,計算字符間的停頓間隔時間,判斷消息幀的起點。當接收到第一個域(地址域)時,每個設備都進行解碼以判斷是否是發給自己的。在最后一個傳輸字符結束之后,一個至少3.5個字符時間的停頓標定了消息的結束,而一個新的消息可在此停頓后開始。另外,在一幀報文中,必須以連續的字符流發送整個報文幀。如果兩個字符之間的空閑間隔大於1.5個字符時間,那么認為報文幀不完整,該報文將被丟棄。

3.5報文需要記住的有:

  • 3.5時間間隔目的是作為區別前后兩幀數據的分隔符
  • 3.5時間間隔只對RTU模式有效

Modbus通信時規定主機發送完一組命令必須間隔3.5個字符再發送下一組新命令,這3.5個字符主要用來告訴其他設備這次命令(數據)已結束。這3.5個字符的時間間隔采用以下方式計算:

通常情況下再串行通信中,1個字符包括1位起始位、8位數據位、1位校驗位(或者沒有)、1位停止位(一般情況下)。這樣一般情況下1個字符就包括11位,那么3.5個字符就是3.5*11=38.5位。

而串行通信中波特率的含義時每秒傳輸的二進制位的個數。例如波特率為9600bps,則意義就是說每1S(也就是1000ms)傳輸9600個位的數據;反過來說傳輸9600個二進制位的數據需要1000ms,那么傳輸38.5個二進制位的數據需要的時間就是:38.5*(1000/9600)=4.0104167ms

Modbus RTU要求相鄰兩幀數據的起始和結束之間至少有大於等於3.5個字符的時間間隔,那么在波特率位9600bps的情況下,只要大於4.0104167即可。

注意:為了實現RTU通信中的時間間隔管理,定時器將引起大量中斷處理,在較高的通信波特率下,這將導致CPU的沉重負擔。為此協議規定當波特率等於或低於19200bps時,需要嚴格遵守時間間隔;而在波特率大於19200bps的情況下,時間間隔使用固定值。建議1.5個字符時間間隔位750us,幀時間間隔位1750us。

地址域

所謂地址域,指的是Modbus通信幀中地址字段,其內容為從設備地址。Modbus消息幀的地址域包括2個字符(ASCII模式)或者1個字節(RTU模式)。

消息幀中可能的從設備地址時0247(十進制)單個設備的實際地址范圍是1247.主設備通過將要聯絡的從設備的地址放入消息中的地址域域來選通從設備。當從設備發送回應消息時,它把自己的地址放入回應的地址域中,以便知道是哪一個設備做出回應。

地址0用作廣播地址,以使所有的從設備都能認識。當Modbus協議用於更高級別的網絡時,廣播方式可能不被允許或以其他方式替代。

0 1~247 248~255
廣播地址 從站地址 保留

功能碼域

功能碼在Modbus協議中用於表示消息幀的功能。

功能碼域由1個字節構成,因此其取值范圍為1~255(十進制)。例如,常用的功能碼有03、04、06、16等,其中03的功能碼的作用是讀保持寄存器內容,04功能碼的作用是讀輸入寄存器內容,06功能碼的內容是預置單個保存寄存器,16功能碼的內容則是預置多個保持寄存器。

從設備根據功能碼執行對應的功能,執行完成后,正常情況下則在返回的響應消息幀中設置同樣的功能碼;如果出現異常,則在返回的消息幀中將功能碼最高位(MSB)設置為1,主設備可獲知對應從設備的執行情況。

另外,對於主設備發送的功能碼,則從設備根據具體配置來決定是否支持此功能碼。如果不支持,則返回異常響應。

數據域

數據域與功能碼緊密相關,存放功能碼需要操作的具體數據。數據域以字節為單位,長度是可變的,對於有些功能碼,數據域可以為空。

Modbus差錯校驗

在Modbus串行通信中,根據傳輸模式(ASCII或RTU)的不同,差錯校驗域采用了不同的校驗方法。

ASCII模式

報文包含一個錯誤校驗字段。該字段由兩個字符組成,其值基於對全部報文內容執行的縱向冗余校驗,計算的結果而來,計算對象不包括起始的冒號(:)和回車換行符。

RTU模式

報文包含一個錯誤校驗字段。與ASCII模式不同的是,該字段由16個比特位共兩個字節組成。其值基於對全部報文內容執行的循環冗余校驗計算結果而來,計算對象包括校驗域之前的所有字節。

LRC校驗

在ASCII模式中,消息是由特定的字符作為幀頭和幀尾來分隔的。

一條消息必須以“冒號”(:)字符(ASCII碼為0x3A)開始,以“回車換行”(CRLF)(ASCII碼為0x0D和0x0A)結束。LRC校驗算法的計算范圍為(:)與(CRLF)之間的字符。

從算法本質來說,LRC域自身為1個字節,即包含一個8位二進制數據,由發送設備通過LRC算法計算,並把計算值附到信息末尾。接收設備在接收信息時,通過LRC算法重新計算值,並把計算值與LRC字段中接收的實際值進行比較。若兩者不同,則產生一個錯誤,返回一個異常響應幀。即對報文中的所有相鄰2個8位字節相加,丟棄任何進位,然后對結果進行二進制補碼,計算出LRC值。

必須注意的是,計算LRC校驗碼的時機,是在對報文中每個原始字節進行ASCII碼編碼之前,對每個原始字節進行LRC校驗的計算操作。

生成LRC校驗值的過程如下:

  1. 對消息幀中的全部字節相加(不包括起始“:”和結束符“CR-LF”),並把結果送入8位數據區,舍棄進位。
  2. 由0xFF(即全1)減去最終的數據值,產生1的補碼(即二進制反碼)。
  3. 加“1”產生二進制補碼。

以上產生的LRC值占用1個字節,但實際上在通過串行鏈路由ASCII模式傳遞消息幀的時候,LRC的結果(1個字節)被編碼為2個字節的ASCII字符,並將其放置在ASCII模式報文幀的CR-LF字段之前。

Modbus標准協議協議英文版提供了LRC的算法。其中參數意義如下:

unsigned char * auchMsg;含有生成LRC所使用的二進制數據的報文緩存區指針。

unsigned short usDataLen;報文緩存區中的字節數。

CRC校驗

在ModbusRTU傳輸模式下,通信報文(幀)包括一個基於循環冗余校驗(CRC)方法的差錯校驗字段。

CRC的全稱是循環冗余校驗,其特點是檢錯能力極強,開銷小,易於用編碼器及檢測電路實現。從其檢錯能力來看,它不能發現的錯誤的機率在0.0047%以下,在Modbus通信中基本可以忽略。CRC校驗包括多個版本,常用的CRC校驗有CRC-8、CRC-12、CRC-16、CRC-CCITT、CRC-32等。

從性能和開銷考慮,CRC校驗均遠遠優於奇偶校驗及算數和校驗等方式,因而在數據儲存和數據通信領域,CRC無處不在。

而在Modbus協議中,則采用了CRC-16標准校驗方法。在RTU模式下,CRC自身由兩個字節組成,即CRC是一個16位的值。CRC字段校驗整個報文的內容,無論報文中的單個字節采用何種奇偶校驗方式,整個通信報文均可應用CRC16校驗算法。CRC字段作為報文的最后字段添加到整個報文末尾。

有一點需要注意,因為CRC-16由兩個字節構成,所以設計那個字節放在前面,那個字節放在后面傳輸的問題,即大小端模式的選擇問題。

接收設備在接收信息時,會通過CRC算法重新計算,並把計算值與CRC字段中接收的實際值進行比較。若兩者不同,則產生一個錯誤,並返回一個異常響應報文(幀)告知發送設備。

Modbus協議中的RTU校驗碼(CRC)計算,運算規則(即CRC計算方法)如下:

  1. 預置一個值位0xFFFF的16位寄存器,此寄存器位CRC寄存器
  2. 把第1個8位二進制數據(即通信消息幀的第一個字節)與16位的CRC寄存器的相異或,異或的結果仍存在於該CRC寄存器中。
  3. 把CRC寄存器的內容右移一位,用0填補最高位,並檢測移出位是0還是1
  4. 如果移出位為零,則重復步驟(3)(再次右移一位);如果移出位位1,則CRC寄存器與0xA001進行異或
  5. 重復步驟(3)和(4),直到右移8次,這樣整個8位數據全部進行了處理。
  6. 重復步驟(2)~(5),進行通信消息幀下一個字節的處理。
  7. 將該通信消息幀所有字節按上述步驟計算完成后,得到的16位CRC寄存器的高、低字節進行交換。即發送時首先添加低位字節,然后添加高位字節。
  8. 最后得到的CRC寄存器內容即為CRC校驗碼

在CRC計算時只有串行鏈路上每個字符中的8個數據為參與計算,而其他比如起始位及停止位,如有奇偶校驗位也包括奇偶校驗位,都不參與CRC計算。

常用的CRC-16查表法和計算法

  1. 查表法

CRC查表法是將移位異或的計算機結果做成了一個表,就是將0~256放入一個長度為16的寄存器中的低8位,高8位填充0,然后將該寄存器與多項式0xA001按照上述步驟(3)、(4),直到8位全部移出,最后寄存器中的值就是表格中的數據,高8位、低8位分別單獨一個表。

實際上,Modbus標准協議英文版提供了CRC查表算法。

函數的輸入參數意義如下:

unsingned char puchMsg /要進行CRC校驗的消息*/

unsingned short usDataLen /消息中字節數/

查表法的特點是:以字節為單位進行計算,速度快,語句少,但是表格占用一定的程序空間。

  1. 計算法

計算法按位計算。這個方法可以適用於所有長度的數據校驗,最為靈活,但由於是按位計算,其效率並不是最優,知識和對速度不敏感的場合。基本的算法如下:

輸入參數的意義:

unsingned char *puchMsg 要進行CRC校驗的消息

unsingned short usDataLen 消息中的字節數

這里舉一個簡單的例子。假設從設備地址位1,要求讀取輸入寄存器地址30001的值,則RTU模式下具體的查詢消息幀如下:

0x01,0x04,0x00,0x00,0x00,0x01,0x31,0xCA

其中,0xCA31即為CRC值。因為Modbus規定發送時CRC必須低字節在前,高字節在后,因此實際的消息幀的發送順序位0x31,0xCA.

字節序和大小端

在學習Modbus協議時,字節序和大小端是一個非常容易忽視而又容易造成困擾的問題。

在計算機里,對於地址的描述,很少用“大”和“小”來形容;對應地,用的更多的是“高”和“低”;很不幸,這對屬於直接按字面翻譯過來就成了“大端”和“小端”。

為什么會有大小端

這是因為在計算機系統中,是以字節為單位的,每個地址單元都對應着一個字節。一個字節位8位(bit)。在C語言中除了8位的char型,還有16位的short型,32位的long型(要看具體的編譯器)。另外,對於位數大於8位的處理器,例如16位或32位處理器,由於寄存器寬度大於一個字節,那么必然存在着一個如何將多個字節安排的問題。因此就導致了大端存儲模式和小端存儲模式。

例如一個16位的short型x,在內存中的地址位0x0010,x的值位0x1122,那么0x11為高字節,0x22為低字節。對於大端模式,就將0x11放在低地址中,即0x0010中;0x22放在高地址中,即0x0011中。對於小端模式,剛好相反。常用的X86結構是小端模式,而KEIL C51則為大端模式。很多ARM、DSP都為小端模式,有些ARM處理器還可以由硬件來選擇是大端模式還是小端模式。

什么是“大端”和“小端”

大端模式,是指數據的低位保存在內存的高地址中,數據的高位保存在內存的低地址中。

小端模式,是指數據的低位保存在內存的低地址中,而數據的高位保存在內存的高地址中。

實際上,Modbus協議中規定一個寄存器占用16位即2個字節長度,因此開發之前有必要搞清楚系統的大小端模式和字節序。

對於32位的整數或者實數來說,存在以下4中不同的字節序(ABCD代表各字節)

  • Long(float)AB CD
  • Long(float)CD AB
  • Long(float)BA DC
  • Long(float)DC BA

例如:若系統采用字節序為AB CD,則十進制整數123456789(其十六進制為 07 5B CD 15)在Modbus消息中發送順序為07 5B CD 15;而十進制實數123456.00(其十六進制為47 F1 20 00),在Modbus消息中發送順序為47 F1 20 00

而對於64位的雙進度實數來說,也存在以下4中不同的字節序:

  • Double AB CD EF GH
  • Double GH EF CD AB
  • Double BA DC FE HG
  • Double HG FE DC BA

例如:若采用字節序AB CE EF GH,則雙精度實數123456789.00(其十六進制為 41 9D 6F 34 54 00 00 00)在Modbus消息中發送順序為41 9D 6F 34 54 00 00 00.

Modbus TCP消息幀格式

協議描述

在Modbus TCP/IP協議中,串行鏈路中的主/從設備分別演變成客戶端/服務器端設備,即客戶端相當於主站設備,服務器端相當於從站設備。基於TCP/IP網絡的傳輸特性,串行鏈路上一主多從的結構也演變為多客戶端/多服務器端的結構模型。Modbus協議在TCP/IP上的實現是在TCP/IP協議層上的應用,它需要一個完整的TCP/IP協議棧作為支撐,Modbus TCP/IP服務器端通常使用端口502作為接收報文的端口。

為了便於傳輸或者提取各報文、保證報文傳輸的完整性,Modbus協議在應用數據單元(ADU)中引入了附加字段。如串行鏈路中,針對ASCII模式分別引入了(:)作為報文分隔標記,並引入LRC作為錯誤校驗;而針對RTU模式則引入了T3.5時間間隔作為報文分隔,引入CRC作為錯誤校驗。

同樣地,在TCP/IP網絡上的Modbus協議也需要引入一個稱為MBAP報文頭的字段。

Modbus TCP/IP 協議最大幀數據長度為260字節,其中字節0~6構成MBAP報頭,各字段意義如下:

字節 字段名 說明 客戶端 服務器端
0 1 Transaction Identifier
傳輸標識
標記某個Modbus查詢/應答的傳輸過程,可以設置為0,也可以設置為每次通信時自動+1 由客戶端生成 應答時復制該值
2 3 Protocol Identifier
協議標識
Modbus協議=0x00標記Modbus協議,設置為0x00 由客戶端生成 應答時復制該值
4 5 Length
字節長度Hi
字節長度Lo
設置為0x00,因此后續字節必須在256字節以內
記錄后續字節的個數
由客戶端生成 應答時重新生成
6 Unit Identifier
單元標識符
用以識別從機設備,例如可以設置為從機設備的地址 由客戶端生成 應答時復制改值
  1. 傳輸標識

傳輸標識用於將查詢報文與未來響應之間建立聯系。因此,對TCP/IP連接來說,在同一時刻,這個標識符必須是唯一的。有幾種使用此標識符的方式:

例如可以將傳輸標識作為一個帶有計數器的簡單“TCP發送順序號”,在每一個請求發送時自動+1;也可以用作智能索引或指針,來識別事務處理的內容,以便記憶當前的遠端服務器和未處理的請求。

服務器端可接受的請求數量取決於其容量,即:服務器資源量和TCP窗口尺寸。同樣,客戶端同時啟動事務處理的數量也取決於客戶機的資源容量。

  1. 單元標識符

在對Modbus或Modbus+等串行鏈路子網中的設備進行尋址時,這個域是用於路由的目的。在這種情況下,“Unit Identifier”攜帶一個遠端設備的Modbus從站地址。

如果Modbus服務器連接到Modbus+或Modbus串行鏈路子網,並通過一個網橋或網關后的子網的從站設備時必須的。TCP連接中的目的IP地址識別了網橋本身的地址,而網橋則使用Modbus單元標識將請求轉交給正確的從站設備。

分配給串行鏈路上的Modbus從站設備地址為1~247(十進制),地址0作為廣播地址。

對單純的Modbus TCP/IP設備來說,利用IP地址即可尋址Modbus服務器端設備,此時Modbus單元標識符是無用的,必須使用值0xFF填充。當對直接連接到TCP/IP網絡上的Modbus服務器尋址時,建議不要在“單元標識符”域使用有效的Modbus從站地址。

以上時MBAP報頭個字段含義的詳細說明。

實際上在Modbus TCP/IP傳輸過程中,服務端(從機)返回的響應報文中同樣包含MBAP報頭,除了Length字段外,其他字段與客戶端一致。Modbus消息幀由TCP/IP層提供,不需要像串行鏈路那樣自己判斷一幀是否結束,所有數據傳輸由TCP/IP層處理。因為底層TCP/IP協議確保了端到端的連接,而且TCP/IP鏈路層已確保傳輸數據的准確性,所以Modbus TCP/IP協議中已不再需要LRC或CRC等校驗功能。

查詢與響應報文例

對於Modbus TCP消息幀格式,舉例說明各部分的含義:

  • 查詢報文:00 00 00 00 00 06 09 03 00 04 00 01

    • 0x06:后續還有6個字節
    • 0x09:單元標識符為9
    • 0x03:功能碼3,即讀保持寄存器的值
    • 0x00 0x04 :Modbus 起始地址4(即40005)
    • 0x00 0x01:讀取寄存器個數為1
  • 響應報文:00 00 00 00 00 05 09 03 02 00 05

    • 0x05:表示后續還有5個字節
    • 0x09:同查詢報文,單元標識符
    • 0x03:功能碼,同查詢報文
    • 0x02:返回數據字節數
    • 0x00 0x05:寄存器的值

可見在Modbus TCP模式下,差錯校驗字段已不復存在。但在某些特殊場合,例如串行Modbus協議轉Modbus TCP的情況下,串行協議數據可以完整地裝載到Modbus TCP協議的數據字段,這時CRC或者LRC差錯校驗字段仍然存在。例如:Modbus RTU Over TCP/IP 或Modbus ASCII Over TCP/IP等。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM