精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

通過面向對象設計串口協議

原創 精選
開發
要想通過串口傳遞具有特定意義的數據時,通常需要對二進制數據加以區分、組合、編碼,以賦予其表達復雜數據結構的能力 —— 串口通信協議。

作者 | 廖桉冬

背景

自Java語言流行以來,其主打的面向對象編程也成為了家喻戶曉的一種程序設計思想:“封裝、繼承、多態”、“易維護、易復用、易擴展”,“解耦、隔離”。

而以過程為中心的“面向過程編程”,通常會優先分析出解決問題所需的步驟,然后用函數依次實現這些步驟,最后串聯起來依次調用即可,是一種基于順序的思維方式。

常見的支持面向過程的編程語言有 C語言、COBOL 語言等,被廣泛地應用在系統內核、IoT、物聯網等領域。其中一個比較典型的案例是串口通信協議的集成開發(驅動、SDK),雖然大多數的Web應用都已經跨入了“Json Free”的時代,但大量的嵌入式設備使用仍是串口協議,以獲得能耗、體積和效率等方面的優勢。而現有的驅動大多由C,使用面向過程的方式編寫的。

舉個栗子 ,當我們的應用需要提供線下的服務:用戶在門戶店可以使用一體機訪問我們的服務,可以選擇使用線下POS機進行刷卡支付(類比肯德基)。我們不僅要在網頁后臺計算出訂單價格,還要通知POS機開始“接單”,完成刷卡操作并及時返回交易數據。

然而,當打開POS機“附贈”的接口文檔時,晃眼的二進制案例、復雜的數據結構卻讓我們手足無措 —— 所有的數據都需要通過那根RS232串口線,以“01010101”的數據與相連的一體機進行交互。

PS:一體機是一臺Windows物理機,通過COM接口(RS232、9針線)連接POS機設備;文章中內含代碼示例,電腦端觀看效果更佳。

令人頭暈的二進制

不同于我們日常所使用的HTTP協議:

  • 具有標準的報文結構和數據編碼
  • 完備的SDK和生態鏈工具,可以很容易實現CS(Client-Server)架構的數據傳輸
  • 無需關注應用層(ISO Application Layer)以下的技術細節

而串口更貼近于ISO的物理層:通過指定頻率(Baud 波特率)的高低電平(0/1)來傳輸數據。

因此要想通過串口傳遞具有特定意義的數據時,通常需要對二進制數據加以區分、組合、編碼,以賦予其表達復雜數據結構的能力 —— 串口通信協議。例如一個典型(但又稍顯復雜)的串口協議報文:

一個串口消息的數據結構(使用16進制表示字節流示例)

串=“串行”,數據在傳輸過程中都是按順序寫入、讀出的,因此需要準確的告訴服務方:

  • StartToken / EndToken,標記當前消息何時開始何時結束
  • Length,當前欲讀取的數據長度

為了提升協議的易用性,將不同目的的數據通過類型加以區分,具有不同的序列化規則:

  • Hex(十六進制)
  • BCD(二進制化整數)
  • ASC(ASIIC碼)

數據部分則由消息頭和多組消息數據組成:

(1)關鍵字段(如ID、Code、Version)都是固定類型、固定長度的數據;

(2)而數據字段(Data)在不同的Field Code(不同場景下)是不同的:

  • 是一個變長數據,因此也需要Len在前,聲明數據長度
  • 發送、讀取時都要通過Field Code動態推斷

按照面向過程的方式按順序依次構建,創建一條消息并不是一件困難的事。然而不同的功能指令(Function Code)所包含的消息數據(Field Data)是完全不一樣的,但其發送流程、序列化方式又是一致的。如果我們面向過程,以一條功能指令為單位進行開發,不僅會出現大量重復冗余的序列化代碼,而且會丟失上層的Function、Field的業務含義, 代碼難以理解和維護。

public void decodeMsgData(byte[] msgDataBlocks, int index) throws PaymentException {
int start = 0;

for(int i = 0; i < msgDataBlocks.length; ++i) {
byte[] fieldCodeByte = new byte[]{msgDataBlocks[start], msgDataBlocks[start + 1]};
String fieldCode = new String(fieldCodeByte);
byte[] lenByte = new byte[]{msgDataBlocks[start + 2], msgDataBlocks[start + 3]};
int len = CommonUtil.convertBCDToInt(lenByte);
byte[] data = new byte[len];
System.arraycopy(msgDataBlocks, start + 4, data, 0, len);

if (!fieldCode.equals("M1") && !fieldCode.equals("HB")) {
if (fieldCode.equals("J4")) {
handleJ4(data);
}
} else if (fieldCode.equals("X5")) {
handleX5(data);
} else if ...
}
}

解析某一種指令的序列化代碼,充斥著難以理解的變量和混亂的處理邏輯

二進制數據的轉換、枚舉值的配置、業務邏輯的處理耦合在同一個類,甚至同一個方法中,想要梳理出代碼的執行流程都已經很困難,更不要說進一步的維護和更新了。

輪子不行就造一個。

“封裝,他使用了封裝!”

那應該如何設計既能夠適配串口數據,又能保證較高的可擴展性和可維護性呢?

  • 遇事不決,量子力學(No )
  • 遇事不決,面向對象(Yes)

面向對象的一大特點就是封裝 —— 高內聚低耦合。

首先,我將三個基本類型進行了封裝:BCD、ASC、Hex,將上層模型(Message)對二進制的依賴逐漸轉移成對基本類型BCD/ASC/Hex的依賴。同理,Start/End Token、分隔符、Length等通用數據類型也被抽取成了單獨的數據類型。

接著,祭出面向對象第二法寶 —— 多態(接口多態),定義Attribute接口來描述“如何由基本類型序列化/反序列化為二進制數據”,并由各個基本類型加以實現。

此時,上層的Message和“0101”已完全解耦,變成了含有多個"基本"字段類型的POJO類。就和我們平時所寫的Class一樣,直接使用String、Int、Double而無需擔心他們在內存的具體地址。

{
"message": {
"startToken": "Hex(08)", // Control.STX
"length": "BCD(128)", // calculate(this)
"header": {
"id": "ASC(000000000001)",
"function": "ASC(01)"
},
"data": [
{
"field": "ASC(M1)",
"length": "BCD(27)",
"value": "ASC(Hello, World)",
"separator": "Hex(1C)" // Control.SEP
}
],
"endToken": "Hex(09)", // Control.ETX
"checksum": "Hex(35)" // calculate(this)
}
}

以對象描述消息結構,以類型標明字段信息

消息對象與“基本類型”的關系

一層一層又一層

封裝之后的Message易于使用了,但開發時仍需要基于業務指令來拼裝數據,只是從對二進制的拼裝變成了對Attribute的拼裝,并不足夠表達業務含義:

(1)對于某一項指令功能(Function)的使用者來說

  • 他不關心下層數據如何被序列化、如何被發送
  • 他只關心業務數據是否正確的被設置和接收(set/get)

(2)對于某一條消息數據(Message)的傳輸者來說

  • 他不關心上層數據的業務含義
  • 他只關心二進制數據的在串口正確的傳輸

多重施法!—— 就像Attribute隔離基本類型與二進制,我們再抽象一個Field接口來隔離業務字段和消息數據。

對于指令使用者(應用開發者)來說,對某一條指令的操作更貼近命令式編程,而下層的消息組裝、序列化以及數據傳輸都被封裝到了“基本字段 Field”和“基本類型 Attribute”中。因為使用了繼承和多態,其他組件通過統一的接口類型進行協作,保證單向依賴和數據的單向流動,大大增加了可擴展性和可維護性。

@FieldDef(code = "49", length = 12)
class TransactionAmount implements Field {
Bigdecimal amount;
}
@FieldDef(code = "51", length = 25)
class AcquirerName implements Field {
String name;
}

{
"request": {
"id": "000000000001", // -> message.header.id
"function": "CREDIT_CARD", // -> message.header.function
"transactionAmount": "20.00", // message.data[]{ field:"49", value:"20.00", ... }
"acquirerName": "VISA" // message.data[]{ field:"51", value:"VISA", … }
}
}

基于消息對象再抽象一層,構建出更貼近業務的Request/Response

對指定指令 (function) 的開發和使用與底層數據結構是解耦的

  • 當我們要支持新的指令時,我們只需要實現新的Field即可 —— function 層以上
  • 當我們要更新序列化規則時,我們只需要修改協議層Attribute —— protocol 層以下

全景

SDK架構 + 數據序列化流向 + 串口異步監聽

測試

Of course,為了避免破壞已經構建好的功能,測試也是開發過程中需要慎重對待的環節(畢竟對于二進制數據來說,前面錯漏一個bit,解碼出來的消息可能完全不一樣...)

對于協議層(protocol),TDD是最佳的測試和開發方式。“A->B”,輸入輸出明確,用起來是非常舒服且高效的。但一旦涉及到串口通信部分就需要費一些心思了:

(1)串口的讀寫口是不一樣的:

  • 寫口發送數據后,需要等待并監聽讀口接收數據
  • 但Listener模式大多是多線程的,需要引入額外的同步組件來控制

(2)串口連接是長鏈接,且沒有容錯機制,可能出現丟包、斷線等情況:

  • 一般會額外設計ACK/NACK的握手機制(類似TCP)來保證通信,以觸發重試

Option 1:構造多線程測試環境

創建Stub Server:

使用了PipedInputStream、PipedOutputStream,將對串口的讀寫流包裝并導向創建的管道流中,再通過另一個線程來模擬終端POS機消費里面的數據,以實現接收請求、返回數據,驗證數據傳輸和序列化的正確性。

val serverInputStream         = PipedInputStream()
val serverOutputStream = PipedOutputStream()
val clientInputStream = PipedInputStream(serverOutputStream)
val clientOutputStream = PipedOutputStream(serverInputStream)
val serialConnection = StreamSerialChannel(clientInputStream, clientOutputStream)

val mockServer = Thread {
// 1. wait for client
Thread.sleep(50)
// 2. read request in server side
serverInputStream.read(ByteArray(requestBytes.size))
// 3. send ack to client
serverOutputStream.write(Acknowledgement.ACK.getBytes())
// 4. notify client - simulate comm listener
serialConnection.onDataAvailable()
// 5. send response to client
serverOutputStream.write(responseBytes)
// 6. notify client - simulate comm listener
serialConnection.onDataAvailable()
// 7. wait for client
Thread.sleep(50)
// 8. read ack in server side
serverInputStream.read(ByteArray(1))
}

左右互搏,模擬上下游的字節流進行數據傳輸

Option 2:使用Fake的外部程序

(1) 虛擬串口:Windows和Linux上有比較成熟的串口調試工具

我使用的是Windows Virtual Serial Port Driver,因為通過虛擬串口直接寫入(二進制)數據并不是很方便,所以我創建了兩個虛擬串口A - B分別模擬Client(發送方-一體機)和Server(接收方-POS)的串口,并連接到一起以便相互通信。與Option 1類似,啟動兩個線程分別扮演發送方、接收方并連接對應的串口,一個發一個收來模擬E2E的交互場景。

(2) USB轉串口芯片(稍微硬核)

剛好家里有一臺樹莓派,本身是自帶串口接口的,可以用來扮演POS系統。然后我從某寶購入了一塊USB轉TTL的串口芯片(因為我的電腦已經沒有九針接口了),插入到Windows主機上,使其可以通過USB向外發送串口數據。將樹莓派和TTL的Read/Write引腳反接,類似Option 2的測試方式,只是兩個線程變成了兩臺獨立主機。

CH340芯片

Option 3:使用測試機

IoT設備相對復雜,一般供應商都會提供相應的測試機器和測試環境。

但由于溝通原因,我們的測試機器很晚才拿到;因為疫情,開發人員并不能接觸到POS測試機,只能通過Zoom遠程指導式調試。因此我們需要盡早、盡快的在相對準確的環境下,驗證SDK的功能是完備的。

也因為我們提前準備的多層測試,在拿到測試機后僅花費了1小時就完成了實機集成測試。

后記(腦補)

本文主要以“面向對象”的編程思想,從新審視了串口協議的設計和實現。利用“封裝、繼承、多態”的特性,構建出更健壯、強擴展、易維護的SDK。但“面向對象”也并不是唯一解—

“抽象 —— 編程的本質,是對問題域和解決方案域的一種提煉”

筆者認為,“抽象”可能是一種更通用的編程思想。選擇合適的角度和層級分析問題,找尋共性并獲得答案,將解決問題的過程抽象為模型、方法論、原則,并推行到更多的場景和領域才是編程的核心。代碼實現僅是一個“翻譯”工作而已。

隨著抽象層級的不同,軟件從代碼、模塊的復用,上升到系統、產品的復用。就像文中的串口協議一樣,只基于下層服務給出承諾和約定,上層應用專注在當前待解決的問題領域。因此,上文雖然是闡述對串口協議的開發設計,但抽象的思維模式依然可以在不同的領域產生共鳴:

  • 高級語言 是對 匯編指令 的抽象和封裝
  • Deployment 是對 Kubernetes多個資源 的抽象和封裝
  • 云服務 是對 軟/硬件服務 的抽象和封裝
責任編輯:趙寧寧 來源: Thoughtworks洞見
相關推薦

2022-07-30 23:41:53

面向過程面向對象面向協議編程

2013-04-17 10:46:54

面向對象

2012-06-07 10:11:01

面向對象設計原則Java

2023-01-10 09:38:09

面向對象系統

2021-11-23 20:41:05

對象軟件設計

2010-06-17 16:06:18

串口協議

2013-06-07 11:31:36

面向對象設計模式

2012-12-25 10:51:39

IBMdW

2010-07-08 10:47:42

UML面向對象

2011-07-05 15:22:04

程序設計

2011-07-05 15:59:57

面向對象編程

2010-06-17 17:57:10

UML面向對象分析與設

2021-07-02 14:14:14

Python對象設計

2011-07-05 16:05:43

面向對象編程

2010-06-10 10:03:42

UML面向對象

2021-07-16 10:23:47

Python設計對象

2024-05-10 09:28:57

Python面向對象代碼

2009-09-27 14:12:12

面向對象設計單一職責

2010-06-18 11:28:14

2023-12-08 07:59:41

對象設計設計模式軟件設計
點贊
收藏

51CTO技術棧公眾號

segui88久久综合| 欧美性精品220| 91黄色小视频| 91中文在线视频| 久久久久麻豆v国产精华液好用吗| 久久久精品人妻一区二区三区四| 麻豆免费在线| 欧美自拍偷拍| 一级做a爱片久久| 欧美成人免费观看| 不卡av免费在线| 在线国产电影不卡| 素人av在线| 一区二区三区四区五区视频在线观看| 精品亚洲aⅴ无码一区二区三区| 一本色道久久综合亚洲精品按摩| 免费黄网站在线播放| 含羞草久久爱69一区| 国产乱色国产精品免费视频| 黄色在线观看国产| 不卡毛片在线看| 国产精品97| 91免费版黄色| 你微笑时很美电视剧整集高清不卡 | av女在线播放| 国产原创一区二区三区| 精品国产一区二区三区av性色 | 亚洲xxx在线观看| 日韩视频在线观看视频| 久久久久久久久久久黄色 | 野外做受又硬又粗又大视频√| 91蝌蚪porny九色| 成人午夜一级| 亚洲大胆视频| 欧美一区二区三区视频在线| 欧美日韩无遮挡| 久久久久成人网站| 成人网18免费网站| 亚洲国产另类久久精品 | 婷婷免费在线观看| 青青青草原在线| 国语对白精品一区二区| 欧美第一区第二区| www.好吊操| 麻豆视频在线观看免费网站| 久久毛片高清国产| 国产z一区二区三区| 欧美精品欧美极品欧美激情| 成人在线视频www| 亚洲欧洲99久久| 成人免费网站在线看| 日韩在线观看免| 亚洲国产伊人| 亚洲自拍偷拍av| 91香蕉视频网址| 久操免费在线| 高清免费成人av| 国内成人精品视频| 国产色视频一区二区三区qq号| 原纱央莉成人av片| 欧美国产97人人爽人人喊| 国产成人97精品免费看片| 国产成人在线免费观看视频| 国产成人一区| 91精品国产麻豆国产自产在线| 亚洲一级片免费| 日本无删减在线| 91亚洲大成网污www| 国产精品一区二区欧美黑人喷潮水| 亚洲国产综合久久| 国产一区二区区别| 亚洲色图激情小说| xxx中文字幕| 欧美gv在线| 日韩欧美有码在线| 91av俱乐部| 手机av在线播放| 一区二区三区在线视频观看58| 糖心vlog在线免费观看| 午夜成人免费影院| 免费人成网站在线观看欧美高清| 北条麻妃一区二区三区中文字幕| 波多野结衣三级视频| 中文字幕资源网在线观看免费| 1000部国产精品成人观看| 日韩精品乱码av一区二区| 亚洲乱码一区av黑人高潮| 黄色片视频在线播放| 黄av在线免费观看| 一区二区三区在线播放| 日韩激情视频一区二区| 黄色网址在线播放| 国产精一品亚洲二区在线视频| 亚洲a级在线观看| 日韩在线视频免费| 狠狠色2019综合网| 91av在线看| 永久免费看片直接| 欧美日韩蜜桃| 色999日韩欧美国产| 国产精品无码毛片| 爱高潮www亚洲精品| 在线91免费看| 免费av网址在线| 超清av在线| 亚洲人成人一区二区在线观看| 日韩一区二区三区高清| 日韩a级作爱片一二三区免费观看| 国产网站一区二区三区| 玛丽玛丽电影原版免费观看1977 | 娇小11一12╳yⅹ╳毛片| 亚洲宅男一区| 亚洲第一男人av| 国产成人av免费观看| 国内精品视频| 色呦呦国产精品| 国产人妻精品久久久久野外| 欧美猛男同性videos| 欧美精品第一页在线播放| 69av.com| 91成人网在线观看| 精品国内亚洲在观看18黄| 欧美日韩国产黄色| 极品尤物久久久av免费看| 国产精品久久二区| 日韩精品在线免费视频| 好吊视频一区二区三区四区| 国产成人免费av电影| 蜜桃91麻豆精品一二三区| 免费精品视频在线| 国产精品一区二区a| 国产午夜在线视频| 波多野结衣视频一区| 国产精品日韩一区| 亚洲网站在线免费观看| 免费看亚洲片| 97精品伊人久久久大香线蕉| 国产天堂av在线| 97精品一区二区| 日韩亚洲精品电影| 久久视频免费在线播放| 男生草女生视频| 激情国产一区| 91深夜福利视频| 又骚又黄的视频| 菠萝蜜视频在线观看一区| 亚洲一区精品视频| 日韩在线视频免费| 欧美激情资源网| 在线观看日本一区| 无遮挡动作视频在线观看免费入口| 亚洲一区二区中文在线| 免费看啪啪网站| 伊人久久精品一区二区三区| 日韩一卡二卡三卡| 青娱乐国产精品视频| 国产日产一区| 51视频国产精品一区二区| 国产免费美女视频| 老司机精品视频在线| 国产97在线|日韩| 黑人精品无码一区二区三区AV| 亚洲精品少妇| 久久男人的天堂| 一级黄色片在线| 国产91在线|亚洲| 超碰97免费观看| 四虎成人精品一区二区免费网站| 亚洲香蕉成人av网站在线观看 | 亚洲国产一区二区三区a毛片 | 每日在线观看av| 青草av在线| 怡红院av一区二区三区| 中文字幕视频三区| 久久美女视频| 日本精品久久久| 中文字幕在线观看第二页| 色综合999| 久久综合色综合88| 日本在线观看a| 国产成人久久| 91久久久久久久久久久久久| 日本综合在线| 欧美群妇大交群中文字幕| 男人女人黄一级| jiujiure精品视频播放| 最近2019中文字幕大全第二页| 青青青国产在线 | 欧美午夜精品久久久久久超碰| 魔女鞋交玉足榨精调教| 美美哒免费高清在线观看视频一区二区 | 欧美高清性xxxx| 免费一级片91| 国产91沈先生在线播放| 国产九一精品| 成人精品久久一区二区三区| 国产精品久久久久久久龚玥菲 | 男人操女人免费软件| 狠狠色狠狠色综合婷婷tag| 国产在线日韩在线| 国产成人三级在线播放| 久久久国产精品麻豆| 国产一区亚洲二区三区| 久久中文字幕二区| 国产富婆一区二区三区| 欧美xxxxxx| 欧美tickling网站挠脚心| 中文字幕在线看高清电影| 青草av.久久免费一区| 欧美三级午夜理伦三级老人| 国产欧美三级电影| 国产精品久久久久久久久影视 | 国模精品视频一区二区| 国产在线三区| 日韩欧美激情在线| 成人在线免费看视频| 亚洲欧美激情在线| 国产黄色网址在线观看| 国产揄拍国内精品对白| 免费毛片小视频| 91精品啪在线观看国产81旧版| 欧美精品一区在线发布| 欧美激情精品| 国产精品国产亚洲伊人久久 | 亚洲在线免费播放| 欧美三级视频网站| 亚洲激情网址| 亚洲精品二区| 麻豆一区二区| 亚洲中国色老太| 欧美最新精品| 亚洲美女精品成人在线视频| 99在线观看免费| 色狠狠桃花综合| 国产亚洲精品久久777777| 中文文精品字幕一区二区| 女同性恋一区二区三区| 亚洲影院免费| 97av中文字幕| 亚洲精品观看| 国产精品电影久久久久电影网| 美女免费久久| 国产亚洲欧美另类中文| 欧美777四色影视在线| 亚洲成a人片在线不卡一二三区 | 97伦伦午夜电影理伦片| 成人中文字幕合集| 人妻av无码专区| 香蕉视频一区| 欧美极品色图| 性欧美lx╳lx╳| 激情小说综合网| 精品91福利视频| 3d精品h动漫啪啪一区二区| 欧美成人毛片| 国产伦精品一区二区三区精品视频| www亚洲人| 亚洲欧美制服第一页| 欧美69xxxxx| 亚洲人成网站在线播| 亚洲图片欧美另类| av日韩一区| yw.139尤物在线精品视频| 日本午夜在线| 欧美另类女人| 成人www视频在线观看| 欧美亚洲黄色| 国产精品中文在线| 粉嫩av一区二区三区四区五区 | 国产盗摄一区二区| 色综合久久悠悠| 日本三级韩国三级欧美三级| 九九九久久国产免费| 电影在线观看一区| 欧美一级淫片aaaaaaa视频| 手机在线观看av| 日韩av免费看| 久久91超碰青草在哪里看| 亚洲专区国产精品| theporn国产在线精品| 好吊色欧美一区二区三区视频| 欧美综合自拍| 狠狠色狠狠色综合人人| 综合国产视频| 视频一区视频二区视频三区视频四区国产 | 欧美中在线观看| 久久野战av| 国产色婷婷国产综合在线理论片a| 青青国产精品| 97伦理在线四区| 九一精品国产| 一区中文字幕在线观看| 欧美午夜免费影院| 精品久久一二三| 视频一区二区不卡| 成年丰满熟妇午夜免费视频 | 国产精品香蕉国产| 亚洲天堂男人av| 欧美视频一区二| 一区二区精品视频在线观看| 欧美一区二区私人影院日本| 天堂中文在线官网| 亚洲一区二区在线观看视频 | 国产91精品在线| 亚洲一区二区三区久久| 欧美日韩一区二区三区不卡视频| 亚洲 国产 欧美一区| 欧美国产91| 亚洲中文字幕无码不卡电影| 精久久久久久久久久久| 俄罗斯黄色录像| 亚洲国产精品v| 特级片在线观看| 日本道免费精品一区二区三区| 国产情侣在线播放| 色就色 综合激情| 亚洲网站免费观看| 亚洲成人精品在线| 91视频在线观看| 性色av一区二区咪爱| 日韩三级成人| 欧日韩一区二区三区| 欧美日韩专区| 日韩一级免费片| 成人涩涩免费视频| 日韩国产第一页| 日本韩国一区二区三区| 亚洲男女视频在线观看| 自拍偷拍亚洲欧美| 欧美日韩成人影院| 国产精品视频在线免费观看| 日韩免费av| 日韩黄色影视| 精品白丝av| 午夜一级免费视频| 91丨九色丨蝌蚪丨老版| 天天综合天天做| 欧美日韩国产一二三| 成年人视频在线看| 欧洲成人在线视频| av成人资源| 成人在线观看毛片| 国产精品亚洲视频| 国产极品美女在线| 精品视频全国免费看| 你懂的免费在线观看视频网站| 久久免费视频网站| 视频一区视频二区欧美| 最新欧美日韩亚洲| 麻豆精品久久精品色综合| zjzjzjzjzj亚洲女人| 亚洲一区av在线| av中文字幕播放| 日日骚久久av| 国内自拍亚洲| 色中文字幕在线观看| 美女在线视频一区| 手机毛片在线观看| 日本韩国欧美一区二区三区| 九色视频网站在线观看| 欧洲成人免费视频| 亚洲宅男一区| 欧美三级一级片| 国产亚洲综合在线| 黄色污污网站在线观看| 欧美性生交大片免费| 天堂中文在线观看视频| 热久久美女精品天天吊色| 极品国产人妖chinesets亚洲人妖 激情亚洲另类图片区小说区 | 美腿丝袜在线亚洲一区 | 澳门黄色一级片| 91超碰这里只有精品国产| 黄网站视频在线观看| 99国产高清| 国模一区二区三区| 一二三区视频在线观看| 亚洲成a人片在线观看中文| 水莓100在线视频| 亚洲精品99久久久久| 99在线视频影院| 国产偷国产偷亚洲高清97cao| 久久99蜜桃| 97国产精东麻豆人妻电影| 国产欧美一区二区精品久导航| 国产99免费视频| 深夜福利91大全| 国产午夜亚洲精品一级在线| 麻豆tv在线播放| 久久一区二区视频| 91丨九色丨海角社区| 久久激情五月丁香伊人| 精品国产一区二区三区成人影院| 美女日批免费视频| 国产午夜精品一区二区三区嫩草| 日本免费精品视频| 九九久久久久久久久激情| 鲁大师精品99久久久| 天堂在线资源视频| 一区二区在线看| 搞黄视频在线观看|