成人性生交大片免费看视频r_亚洲综合极品香蕉久久网_在线视频免费观看一区_亚洲精品亚洲人成人网在线播放_国产精品毛片av_久久久久国产精品www_亚洲国产一区二区三区在线播_日韩一区二区三区四区区区_亚洲精品国产无套在线观_国产免费www

主頁 > 知識庫 > 使用golang寫一個redis-cli的方法示例

使用golang寫一個redis-cli的方法示例

熱門標(biāo)簽:學(xué)海導(dǎo)航地圖標(biāo)注 中國地圖標(biāo)注省會高清 南通如皋申請開通400電話 高德地圖標(biāo)注口訣 廣州呼叫中心外呼系統(tǒng) 江西轉(zhuǎn)化率高的羿智云外呼系統(tǒng) 浙江高速公路地圖標(biāo)注 西部云谷一期地圖標(biāo)注 地圖標(biāo)注的汽車標(biāo)

0. redis通信協(xié)議

redis的客戶端(redis-cli)和服務(wù)端(redis-server)的通信是建立在tcp連接之上, 兩者之間數(shù)據(jù)傳輸?shù)木幋a解碼方式就是所謂的redis通信協(xié)議。所以,只要我們的redis-cli實現(xiàn)了這個協(xié)議的解析和編碼,那么我們就可以完成所有的redis操作。

redis 協(xié)議設(shè)計的非常易讀,也易于實現(xiàn),關(guān)于具體的redis通信協(xié)議請參考:通信協(xié)議(protocol)。后面我們在實現(xiàn)這個協(xié)議的過程中也會簡單重復(fù)介紹一下具體實現(xiàn)

1. 建立tcp連接

redis客戶端和服務(wù)端的通信是建立tcp連接之上,所以第一步自然是先建立連接

package main

import (
 "flag"
 "log"
 "net"
)

var host string
var port string

func init() {
 flag.StringVar(host, "h", "localhost", "hsot")
 flag.StringVar(port, "p", "6379", "port")
}

func main() {
 flag.Parse()

 tcpAddr := net.TCPAddr{IP: net.ParseIP(host), Port: port}
 conn, err := net.DialTCP("tcp", nil, tcpAddr)
 if err != nil {
 log.Println(err)
  }
  defer conn.Close()

 // to be continue
}

后續(xù)我們發(fā)送和接受數(shù)據(jù)便都可以使用conn.Read()和conn.Write()來進行了

2. 發(fā)送請求

發(fā)送請求第一個第一個字節(jié)是"*",中間是包含命令本身的參數(shù)個數(shù),后面跟著"\r\n" 。之后使用"$"加參數(shù)字節(jié)數(shù)量并使用"\r\n"結(jié)尾,然后緊跟參數(shù)內(nèi)容同時也使用"\r\n"結(jié)尾。如執(zhí)行 SET key liangwt 客戶端發(fā)送的請求為"*3\r\n$3\r\nSET\r\n$3\r\nkey\r\n$7\r\nliangwt\r\n"

注意:

  1. 命令本身也作為協(xié)議的其中一個參數(shù)來發(fā)送
  2. \r\n 對應(yīng)byte的十進制為 13 10

我們可以使用telnet測試下

wentao@bj:~/github.com/liangwt/redis-cli$ telnet 127.0.0.1 6379
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
*3
$3
SET
$3
key
$7
liangwt
+OK

先暫時忽略服務(wù)端的回復(fù),通過telnet我們可以看出請求協(xié)議非常簡單,所以對于請求協(xié)議的實現(xiàn)不做過多的介紹了,直接放代碼(如下使用基于字符串拼接,只是為了更直觀的演示,效率并不高,實際代碼中我們使用bytes.Buffer來實現(xiàn))

func MultiBulkMarshal(args ...string) string {
 var s string
 s = "*"
 s += strconv.Itoa(len(args))
 s += "\r\n"

 // 命令所有參數(shù)
 for _, v := range args {
 s += "$"
 s += strconv.Itoa(len(v))
 s += "\r\n"
 s += v
 s += "\r\n"
 }

 return s
}

在實現(xiàn)了對命令和參數(shù)進行編碼之后,我們便可以通過conn.Write()把數(shù)據(jù)推送到服務(wù)端

func main() {
  // ....
 req := MultiBulkMarshal("SET", "key", "liangwt")
 _, err = conn.Write([]byte(req))
 if err != nil {
 log.Fatal(err)
 }
 // to be continue
}

3. 獲取回復(fù)

我們首先實現(xiàn)通過tcp獲取服務(wù)端返回值,就是上面提到過的conn.Read()。

func main() {
  // ....
 p := make([]byte, 1024)
 _, err = conn.Read(p)
 if err != nil {
 log.Fatal(err)
 }
 // to be continue
}

4. 解析回復(fù)

我們拿到p之后我們就可以解析返回值了,redis服務(wù)端的回復(fù)是分為幾種情況的

  • 狀態(tài)回復(fù)
  • 錯誤回復(fù)
  • 整數(shù)回復(fù)
  • 批量回復(fù)
  • 多條批量回復(fù)

我們把前四種單獨看作一組,因為他們都是單一類型的返回值

我們把最后的多條批量回復(fù)看成單獨的一組,因為它是包含前面幾種類型的混合類型。而且你可以發(fā)現(xiàn)它和我們的請求協(xié)議是一樣的

也正是基于以上的考慮我們創(chuàng)建兩個函數(shù)來分別解析單一類型和混合類型,這樣在解析混合類型中的某一類型時就只需要調(diào)用單一類型解析的函數(shù)即可

在解析具體協(xié)議前我們先實現(xiàn)一個是讀取到\r\n為止的函數(shù)

func ReadLine(p []byte) ([]byte, error) {
 for i := 0; i  len(p); i++ {
 if p[i] == '\r' {
  if p[i+1] != '\n' {
  return []byte{}, errors.New("format error")
  }
  return p[0:i], nil
 }
 }
 return []byte{}, errors.New("format error")
}

第一種狀態(tài)回復(fù):

狀態(tài)回復(fù)是一段以 "+" 開始, "\r\n" 結(jié)尾的單行字符串。如 SET 命令成功的返回值:"+OK\r\n"

所以我們判斷第一個字符是否等于 '+' 如果相等,則讀取到\r\n

func SingleUnMarshal(p []byte) ([]byte, int, error) {
 var (
 result []byte
 err  error
 length int
 )
 switch p[0] {
 case '+':
 result, err = ReadLine(p[1:])
 length = len(result) + 3
 }

 return result, length, err
}

注:我們在返回實際回復(fù)內(nèi)容的同時也返回了整個回復(fù)的長度,方便后面解析多條批量回復(fù)時定位下一次的解析位置

第二種錯誤回復(fù):

錯誤回復(fù)的第一個字節(jié)是 "-", "\r\n" 結(jié)尾的單行字符串。如執(zhí)行 SET key缺少參數(shù)時返回值:"-ERR wrong number of arguments for 'set' command\r\n"

錯誤回復(fù)和狀態(tài)回復(fù)非常相似,解析方式也是一樣到。所以我們只需添加一個case即可

func SingleUnMarshal(p []byte) ([]byte, int, error) {
 var (
 result []byte
 err  error
 length int
 )
 switch p[0] {
 case '+', '-':
 result, err = ReadLine(p[1:])
 length = len(result) + 3
 }
 return result, length, err
}

第三種整數(shù)回復(fù):

整數(shù)回復(fù)的第一個字節(jié)是":",中間是字符串表示的整數(shù),"\r\n" 結(jié)尾的單行字符串。如執(zhí)行LLEN mylist命令時返回 ":10\r\n"

整數(shù)回復(fù)也和上面兩種是一樣的,只不過返回的是字符串表示的十進制整數(shù)

func SingleUnMarshal(p []byte) ([]byte, int, error) {
 var (
 result []byte
 err  error
 length int
 )
 switch p[0] {
 case '+', '-', ':':
 result, err = ReadLine(p[1:])
 length = len(result) + 3
 }
 return result, length, err
}

第四種批量回復(fù):

批量回復(fù)的第一個字節(jié)為 "$",接下來是字符串表示的整數(shù),它表示實際回復(fù)的長度,之后跟著一個 "\r\n",再后面跟著的是實際回復(fù)數(shù)據(jù),最末尾是另一個 "\r\n"。如GET key 命令的返回值:"$7\r\nliangwt\r\n"

所以批量回復(fù)解析的實現(xiàn):

  • 讀取第一行得到實際回復(fù)的長度
  • 把字符串類型的長度轉(zhuǎn)換成對應(yīng)十進制整數(shù)
  • 從第二行開始位置往下讀對應(yīng)長度

但是對于某些不存在的key,批量回復(fù)會將特殊值 -1 用作回復(fù)的長度值, 此時我們不需要繼續(xù)往下讀取實際回復(fù)。例如GET NOT_EXIST_KEY 返回值:"$-1", 所以我們需要對此特殊情況判斷,讓函數(shù)返回一個空對象(nil)而不是空值("")

func SingleUnMarshal(p []byte) ([]byte, int, error) {
 // ....
 case '$':
 n, err := ReadLine(p[1:])
 if err != nil {
  return []byte{}, 0, err
 }
 l, err := strconv.Atoi(string(n))
 if err != nil {
  return []byte{}, 0, err
 }
 if l == -1 {
  return nil, 0, nil
 }
 // +3 的原因 $ \r \n 三個字符
 result = p[len(n)+3 : len(n)+3+l]
 length = len(n) + 5 + l
 }
 return result, length, err
}

思考:

為什么redis要使用提前告知字節(jié)數(shù),然后往下讀取指定長度的方式,而不是直接讀取第二行到\r\n為止?

答案很明顯:此方式可以讓redis讀取返回值時不受具體的返回內(nèi)容影響,在按行讀取的情況下,無論使用任何分割符都有可能導(dǎo)致redis在解析具體內(nèi)容時把內(nèi)容中的分割符當(dāng)作時結(jié)尾,導(dǎo)致解析錯誤。

思考一下這種情況:我們SET key "liang\r\nwt" ,那么當(dāng)我們GET key時,服務(wù)端返回值為"$9\r\nliang\r\nwt\r\n" 完全規(guī)避了value中的\r\n影響

第五種多條批量回復(fù):

多條批量回復(fù)是由多個回復(fù)組成的數(shù)組,它的第一個字節(jié)為"*", 后跟一個字符串表示的整數(shù)值, 這個值記錄了多條批量回復(fù)所包含的回復(fù)數(shù)量, 再后面是一個"\r\n"。如LRANGE mylist 0 -1的返回值:"*3\r\n$1\r\n3\r\n$1\r\n2\r\n$1\r\n1"。

所以多條批量回復(fù)解析的實現(xiàn):

  • 解析第一行數(shù)據(jù)獲得字符串類型的回復(fù)數(shù)量
  • 把字符串類型的長度轉(zhuǎn)換成對應(yīng)十進制整數(shù)
  • 按照單條回復(fù)依次逐個解析,一共解析成上面得到的數(shù)量

在這里我們用到了單條解析時返回的字節(jié)長度length,通過這個長度我們可以很方便的知道下次單條解析的開始位置為上一次位置+length

在解析多條批量回復(fù)時需要注意兩點:

第一,多條批量回復(fù)也可以是空白的(empty)。例如執(zhí)行LRANGE NOT_EXIST_KEY 0 -1 服務(wù)端返回值"*0\r\n"。此時客戶端返回的應(yīng)該空數(shù)組[][]byte

第二,多條批量回復(fù)也可以是無內(nèi)容的(null multi bulk reply)。例如執(zhí)行BLPOP key 1 服務(wù)端返回值"*-1\r\n"。此時客戶端返回的應(yīng)該是nil

func MultiUnMarsh(p []byte) ([][]byte, error) {
 if p[0] != '*' {
 return [][]byte{}, errors.New("format error")
 }
 n, err := ReadLine(p[1:])
 if err != nil {
 return [][]byte{}, err
 }
 l, err := strconv.Atoi(string(n))
 if err != nil {
 return [][]byte{}, err
 }
 // 多條批量回復(fù)也可以是空白的(empty)
 if l == 0 {
 return [][]byte{}, nil
 }

 // 無內(nèi)容的多條批量回復(fù)(null multi bulk reply)也是存在的,
 // 客戶端庫應(yīng)該返回一個 null 對象, 而不是一個空數(shù)組。
 if l == -1 {
 return nil, nil
 }
 result := make([][]byte, l)
 t := len(n) + 3
 for i := 0; i  l; i++ {
 ret, length, err := SingleUnMarshal(p[t:])
 if err != nil {
  return [][]byte{}, errors.New("format error")
 }
 result[i] = ret
 t += length
 }

 return result, nil
}

5. 命令行模式

一個可用的redis-cli自然是一個交互式的,用戶輸入指令然后輸出返回值。在go中我們可以使用以下代碼即可獲得一個類似的交互式命令行

func main() {
 // ....
 for {
 fmt.Printf("%s:%d>", host, port)

 bio := bufio.NewReader(os.Stdin)
 input, _, err := bio.ReadLine()
 if err != nil {
  log.Fatal(err)
 }
 fmt.Printf("%s\n", input)
 }
}

我們運行以上代碼就可以實現(xiàn)

localhost:6379>set key liang
set key liang
localhost:6379>get key
get key
localhost:6379>

結(jié)合上我們的redis發(fā)送請求和解析請求即可完成整個redis-cli

func main() {
  // ....
 for {
 fmt.Printf("%s:%d>", host, port)

 // 獲取輸入命令和參數(shù)
 bio := bufio.NewReader(os.Stdin)
 input, err := bio.ReadString('\n')
 if err != nil {
  log.Fatal(err)
 }
 fields := strings.Fields(input)

 // 編碼發(fā)送請求
 req := MultiBulkMarshal(fields...)

 // 發(fā)送請求
 _, err = conn.Write([]byte(req))
 if err != nil {
  log.Fatal(err)
 }

 // 讀取返回內(nèi)容
 p := make([]byte, 1024)
 _, err = conn.Read(p)
 if err != nil {
  log.Fatal(err)
 }

 // 解析返回內(nèi)容
 if p[0] == '*' {
  result, err := MultiUnMarsh(p)
 } else {
  result, _, err := SingleUnMarshal(p)
 }

  }
  // ....
}

6. 總結(jié)

到目前為止我們的cli程序已經(jīng)全部完成,但其實還有很多不完美地方。但核心的redis協(xié)議解析已經(jīng)完成,使用這個解析我們能完成任何的cli與服務(wù)器之間的交互

更詳細的redis-cli實現(xiàn)可以參考我的github:A Simaple redis cli - Rclient

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

您可能感興趣的文章:
  • Golang使用lua腳本實現(xiàn)redis原子操作
  • golang實現(xiàn)redis的延時消息隊列功能示例
  • 在Golang中使用Redis的方法示例
  • Golang連接Redis數(shù)據(jù)庫的方法

標(biāo)簽:吐魯番 常州 德宏 曲靖 保定 貴州 東營 許昌

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《使用golang寫一個redis-cli的方法示例》,本文關(guān)鍵詞  使用,golang,寫,一個,redis-cli,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請?zhí)峁┫嚓P(guān)信息告之我們,我們將及時溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《使用golang寫一個redis-cli的方法示例》相關(guān)的同類信息!
  • 本頁收集關(guān)于使用golang寫一個redis-cli的方法示例的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章
    国产成年人在线观看| 777精品视频| 国产精品丝袜一区二区| 神马影院午夜我不卡| 影音先锋2020资源| 草草在线视频| 日本天堂在线观看| 亚洲精品在线一区二区| 亚洲激情播播| 嫩草影院永久一二三入口| 亚洲一卡二卡三卡四卡无卡网站在线看| 男人天堂网页| 国产91色综合久久免费分享| 无码人中文字幕| 91精品一区| 不卡视频在线观看| 亚洲精品911| 精品美女一区二区| 一区二区三区四区国产| 午夜激情影院| 国产精品美女久久久久av福利| 尤物tv国产一区| 99视频在线看| 麻豆明星ai换脸视频| 99re久久最新地址获取| 五月婷婷综合在线观看| 国产精品人人爽人人爽| 国产主播精品在线| 四虎影视成人精品国库在线观看| 日韩国产在线看| 日韩精品一二三四区| 猫咪在线永久网站| 九九久久99| av一区二区三区在线观看| 三上悠亚在线观看二区| 91久久久免费一区二区| 日韩中文在线观看| 日本不卡不码高清免费观看| 国产伊人网av.| 国产精品入口免费| 日本网站在线免费观看视频| 7777精品伊人久久久大香线蕉完整版| 亚洲av毛片基地| 僵尸世界大战2 在线播放| 国产精品久久久久久久一区探花| 国产人妻人伦精品1国产丝袜| 午夜少妇久久久久久久久| 免费成人av在线播放| 亚洲午夜精品17c| 久久手机在线视频| 九九九久久久久久久| 91原创国产| 亚洲成人精品视频在线观看| 免费网站永久免费观看| 国产精品人人妻人人爽人人牛| 精品国产_亚洲人成在线| 成人网18免费看| 黄大色黄女片18免费| 精品日产乱码久久久久久仙踪林| 少妇喷水在线观看| 波多野结衣av在线免费观看| 成人激情黄色小说| 热久久免费视频| 日本少妇性生活| 色诱视频网站一区| 先锋影音一区二区三区| 亚洲综合婷婷久久| 国产成人精品日本亚洲专区61| 日韩av在线免费播放| 亚洲精品水蜜桃| www.亚洲视频.com| 中文字幕中文字幕一区| 91成人在线网站| 欧美jizzhd精品欧美另类| 日韩一区二区三区在线视频| 91蝌蚪porny九色| 亚洲精品永久www嫩草| 久久伊人免费视频| 女主播福利一区| 中文字幕校园春色| 玉米视频成人免费看| 欧美精品三级日韩久久| 亚洲成av人乱码色午夜| 亚洲图片综合网| 在线播放网站| 天堂av最新在线| 国产欧美精品一区二区色综合| 亚洲天堂成人网| 亚洲资源网你懂的| 中文欧美在线视频| 白浆视频在线观看| 性欧美freehd18| 欧美挠脚心网站| 一区二区三区资源| 99re8这里有精品热视频8在线| 国产欧美一区二区三区另类精品| 国产一在线精品一区在线观看| 美女大黄三级视频在线观看| 精品电影在线| 性欧美暴力猛交另类hd| 国产精品免费一区二区三区都可以| ㊣最新国产の精品bt伙计久久| 日韩美一区二区| 精品在线播放午夜| 一区2区3区在线看| 亚洲成年人在线播放| 国产黄色一级网站| 久久久久久亚洲综合| 久久视频精品在线观看| 国产高清亚洲| 欧美日韩电影一区二区三区| 日韩av网站导航| 久久免费大视频| 九色porny丨入口在线| 欧美性感一区二区三区| 久久久99免费视频| 91theporn国产在线观看| 色偷偷精品视频在线播放| 黄色激情视频网址| 国产精品网站一区| 天天躁日日躁狠狠躁av麻豆男男| 久久久久女教师免费一区| 日韩精品免费在线播放| 久久久久久久激情视频| 欧美成人午夜剧场免费观看| 国产精品嫩草69影院| 国产精品无码电影| 国产精品yjizz视频网一二区| 色偷偷偷亚洲综合网另类| 深夜福利一区| 久久久电影免费观看完整版| gogo在线高清视频| 亚洲人精品午夜| 欧美性猛交xxxx免费看| 亚洲国产片色| 亚洲精品自拍视频在线观看| 欧美xxxx黑人又粗又长| 国产精品久久久久一区二区国产| 亚洲成人av中文| 麻豆成人av| 国产欧美日韩中文| 视频在线观看国产精品| 亚洲一区二区影视| 国产精品一级二级三级| 国产手机视频一区二区| 东京热加勒比无码少妇| 手机看片久久| 久久视频在线观看免费| 色婷婷久久综合中文久久蜜桃av| 亚洲一区二区中文字幕| 激情文学一区| 国产超碰91| 国产精品99久久久久| 欧美三级一区| 欧美成人自拍| 在线免费国产视频| 永久看看免费大片| 玖玖玖视频精品| 奇米网人体黄视频| 99久免费精品视频在线观78| 中文字幕久热精品视频在线| 国产九一视频| 欧美日韩亚洲一区在线观看| 日韩av影院在线观看| 国产精品91一区| 91美女片黄在线观看91美女| 成人国产精品色哟哟| 日韩一区在线看| 特级西西444www大精品视频免费看| 另类专区欧美蜜桃臀第一页| 亚洲超碰在线观看| 五月天亚洲综合情| 精品一区二区三孕妇视频| 2222www色视频在线观看| 欧美特黄a级高清免费大片a级| 青青草伊人久久| 欧美扣逼视频| av免费看大片| 欧美日韩破处| 国产二级c片l毛片| 青青草原综合久久大伊人精品优势| va中文字幕| 国产99精品视频| 亚洲精品写真福利| 在线观看国产成人| 亚洲二区在线播放视频| 久久免费看少妇高潮v片特黄| 国产精品99久久久久久宅男| 国产成人精品久久久| 影音先锋国产在线资源| 久久国产加勒比精品无码| 四虎影视成人精品国库在线观看| 精品人妻伦一区二区三区久久| 亚洲少妇30p| 伊人网综合在线| 日本加勒比一区| 国产精品久久久久福利| 中文字幕亚洲精品在线| 亚洲精品成人在线| 一本久道中文无码字幕av| 超碰手机在线观看| 漂亮人妻被黑人久久精品| 亚欧精品一区二区三区| 99久久亚洲精品日本无码| 日韩美女爱爱视频| 僵尸世界大战2 在线播放| 亚洲一级片免费| 欧美中文字幕一区二区三区| 久久九九有精品国产23| 亚洲精品久久久久avwww潮水| 精品国内自产拍在线视频| 天堂av一区二区| 成人动漫精品一区二区| 正在播放欧美一区| 天天堂资源网在线观看免费视频| 国产一区二区三区亚洲综合| 国产综合一区二区| 亚洲综合日韩在线| 久久蜜桃香蕉精品一区二区三区| 欲香欲色天天天综合和网| 久久精品一区二区三| 在线播放av中文字幕| 亚洲激情影院| 久久久无码中文字幕久...| 日韩视频第一页| 欧洲av无码放荡人妇网站| 爆乳熟妇一区二区三区霸乳| 日韩成人av毛片| 青青草av专区| 精品日本一区二区三区| 日韩av影视综合网| 欧美午夜视频| 国产在线精品国自产拍免费| 在线观看日韩一区二区| www.avtt| 久久99精品久久久| 免费黄在线观看| 色偷偷噜噜噜亚洲男人| 国产精品1024久久| 亚洲精品视频免费在线观看| 亚洲小说区图片区| 国产精品亚洲午夜一区二区三区| 中文字幕av专区| 国产又大又黑又粗| 一本久道久久综合婷婷鲸鱼| 免费观看一区二区三区毛片| 四季av综合网站| 欧美人成在线| 91麻豆产精品久久久久久夏晴子| 成熟亚洲日本毛茸茸凸凹| 国模 一区 二区 三区| av女片在线| 国产三区视频在线观看| 加勒比在线一区二区三区观看| 黄色片网站在线播放| 日韩视频免费在线观看| 欧美精品系列| 亚洲国产精品第一页| 亚洲风情在线资源站| 久久影音资源网| 污网站免费在线| 欧美激情视频给我| 在线观看免费国产小视频| 欧美日韩国产综合视频在线| 91久久国产综合久久| 你懂的在线免费观看| 日韩激情精品| 37p粉嫩大胆色噜噜噜| 久久精视频免费在线久久完整在线看| 成人午夜免费剧场| 91人人澡人人爽人人精品| 99re热这里只有精品免费视频| 亚洲热在线视频| 毛片一区二区| 精品国产一区在线| 涩涩网在线视频| 久久av资源| 中文字幕在线字幕中文| 狠狠色综合网站久久久久久久| 国产精品国产成人国产三级| 欧美性猛交xxxx乱大交丰满| 国产在线高清| 亚洲人成无码网站久久99热国产| 菠萝蜜视频在线观看www入口| 伊人影院中文字幕| 亚洲精品中文字幕乱码三区不卡| 奇米影视四色在线| 91精选在线观看| 99视频在线观看免费| 高清不卡日本v二区在线| 欧洲vs亚洲vs国产| 亚瑟一区二区三区四区| 久久久青草婷婷精品综合日韩| 91久久中文字幕| 中文区中文字幕免费看| 欧美美女直播网站| 一区二区不卡在线视频 午夜欧美不卡'| 欧美日韩午夜电影网| 一二三区在线视频| 永久在线免费观看| 亚洲精选在线视频| 亚洲精品中文字幕乱码| 午夜不卡影院| 精品国产一区二区三区噜噜噜| 三级毛片在线免费看| 手机在线播放av| 99欧美精品| 综合久久综合| 成人激情电影在线看| 黄色小视频免费观看| 国模精品一区二区三区| 亚洲无av在线中文字幕| 一色屋色费精品视频在线观看| avav免费在线观看| av成人在线看| 日漫免费在线观看网站| 日韩美女主播在线视频一区二区三区| 中文字幕永久在线不卡| 中文字幕在线视频久| 国产精品高颜值在线观看| 久久久综合九色合综国产精品| 尤物yw午夜国产精品视频明星| 啦啦啦中文在线观看日本| 亚洲不卡中文字幕无码| 亚洲小说春色综合另类电影| 91精品国产高久久久久久五月天| 黄色成人免费网| 久久精品久久久久久久|