国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

腳本之家,腳本語(yǔ)言編程技術(shù)及教程分享平臺(tái)!
分類導(dǎo)航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服務(wù)器之家 - 腳本之家 - Golang - Golang Socket Server自定義協(xié)議的簡(jiǎn)單實(shí)現(xiàn)方案

Golang Socket Server自定義協(xié)議的簡(jiǎn)單實(shí)現(xiàn)方案

2021-03-04 00:50冷月醉雪 Golang

這篇文章主要介紹了Golang Socket Server自定義協(xié)議的簡(jiǎn)單實(shí)現(xiàn)方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧

Server和Client通訊中,由于網(wǎng)絡(luò)等原因很可能會(huì)發(fā)生數(shù)據(jù)丟包的現(xiàn)象。如果數(shù)據(jù)缺失,服務(wù)端接收的信息不完整,就會(huì)造成混亂。

我們需要在Server和Client之間建立一個(gè)通訊協(xié)議,通過(guò)協(xié)議中的規(guī)則,判斷當(dāng)前接收到的信息是否完整。根據(jù)信息的完整情況,采取不同的處理方式。

通訊協(xié)議protocol的核心就是設(shè)計(jì)一個(gè)頭部。如果傳來(lái)的信息不包含這個(gè)頭部,就說(shuō)明當(dāng)前信息和之前的信息是同一條。那么就把當(dāng)前信息和之前的那條信息合并成一條。

而協(xié)議主要包含的功能是封裝(Enpack)和解析(Depack)。Enpack是客戶端對(duì)信息進(jìn)行數(shù)據(jù)封裝。封裝之后可以傳遞給服務(wù)器。Depack是服務(wù)器對(duì)信息進(jìn)行數(shù)據(jù)解析。

其中有個(gè)Const部分,用于定義頭部、頭部長(zhǎng)度、客戶端傳入信息長(zhǎng)度。

在代碼中,我們這樣定義:

?
1
2
3
4
5
const (
 ConstHeader = "Headers"
 ConstHeaderLength = 7
 ConstMLength = 4
)

頭部的內(nèi)容為"Headers",長(zhǎng)度為7。所以ConstHeaderLenth=7.

而信息傳遞過(guò)程中,我們會(huì)把int類型轉(zhuǎn)換成byte類型。一個(gè)int的長(zhǎng)度等于4個(gè)byte的長(zhǎng)度。因此,我們?cè)O(shè)置ConstMLength=4.代表客戶端的傳來(lái)的信息大小。

自定義協(xié)議protocal的代碼示例如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
/**
* protocol
* @Author: Jian Junbo
* @Email: junbojian@qq.com
* @Create: 2017/9/14 11:49
*
* Description: 通訊協(xié)議處理
*/
package protocol
import (
 "bytes"
 "encoding/binary"
)
 
const (
 ConstHeader = "Headers"
 ConstHeaderLength = 7
 ConstMLength = 4
)
 
//封包
func Enpack(message []byte) []byte {
 return append(append([]byte(ConstHeader), IntToBytes(len(message))...), message...)
}
 
//解包
func Depack(buffer []byte) []byte {
 length := len(buffer)
 
 var i int
 data := make([]byte, 32)
 for i = 0; i < length; i++ {
 
  if length < i + ConstHeaderLength + ConstMLength{
   break
  }
  if string(buffer[i:i+ConstHeaderLength]) == ConstHeader {
   messageLength := ByteToInt(buffer[i+ConstHeaderLength : i+ConstHeaderLength+ConstMLength])
   if length < i+ConstHeaderLength+ConstMLength+messageLength {
    break
   }
   data = buffer[i+ConstHeaderLength+ConstMLength : i+ConstHeaderLength+ConstMLength+messageLength]
  }
 }
 
 if i == length {
  return make([]byte, 0)
 }
 return data
}
 
//字節(jié)轉(zhuǎn)換成整形
func ByteToInt(n []byte) int {
 bytesbuffer := bytes.NewBuffer(n)
 var x int32
 binary.Read(bytesbuffer, binary.BigEndian, &x)
 return int(x)
}
 
//整數(shù)轉(zhuǎn)換成字節(jié)
func IntToBytes(n int) []byte {
 x := int32(n)
 bytesBuffer := bytes.NewBuffer([]byte{})
 binary.Write(bytesBuffer, binary.BigEndian, x)
 return bytesBuffer.Bytes()
}

Server端主要通過(guò)協(xié)議來(lái)解析客戶端發(fā)送來(lái)的信息。建立一個(gè)函數(shù),用來(lái)完成連接對(duì)接收信息的處理。其中建立了通道readerChannel,并把接收來(lái)的信息放在通道里。

在放入通道之前,使用protocol和Depack對(duì)信息進(jìn)行解析。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//連接處理
func handleConnection(conn net.Conn) {
 //緩沖區(qū),存儲(chǔ)被截?cái)嗟臄?shù)據(jù)
 tmpBuffer := make([]byte, 0)
 //接收解包
 readerChannel := make(chan []byte, 10000)
 go reader(readerChannel)
 
 buffer := make([]byte, 1024)
 for{
  n, err := conn.Read(buffer)
  if err != nil{
   Log(conn.RemoteAddr().String(), "connection error: ", err)
   return
  }
  tmpBuffer = protocol.Depack(append(tmpBuffer, buffer[:n]...))
  readerChannel <- tmpBuffer  //接收的信息寫(xiě)入通道
 
 }
 defer conn.Close()
}

如果信息讀取發(fā)生錯(cuò)誤(包括讀取到信息結(jié)束符EOF),都會(huì)打印錯(cuò)誤信息,并跳出循環(huán)。

Log(conn.RemoteAddr().String(), "connection error: ", err)

return

由于通道內(nèi)的數(shù)據(jù)是[]byte型的。需要轉(zhuǎn)換成string。這個(gè)工作有專門的獲取通道數(shù)據(jù)的reader(readerChannel chan []byte)來(lái)完成。

?
1
2
3
4
5
6
7
8
9
//獲取通道數(shù)據(jù)
func reader(readerchannel chan []byte) {
 for{
  select {
  case data := <-readerchannel:
   Log(string(data))  //打印通道內(nèi)的信息
  }
 }
}

查看Server端代碼示例:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
/**
* MySocketProtocalServer
* @Author: Jian Junbo
* @Email: junbojian@qq.com
* @Create: 2017/9/14 13:54
* Copyright (c) 2017 Jian Junbo All rights reserved.
*
* Description: 服務(wù)端,接收客戶端傳來(lái)的信息
*/
package main
import (
 "net"
 "fmt"
 "os"
 "log"
 "protocol"
)
 
func main() {
 netListen, err := net.Listen("tcp", "localhost:7373")
 CheckErr(err)
 defer netListen.Close()
 
 Log("Waiting for client ...")  //啟動(dòng)后,等待客戶端訪問(wèn)。
 for{
  conn, err := netListen.Accept()  //監(jiān)聽(tīng)客戶端
  if err != nil {
   Log(conn.RemoteAddr().String(), "發(fā)了了錯(cuò)誤:", err)
   continue
  }
  Log(conn.RemoteAddr().String(), "tcp connection success")
  go handleConnection(conn)
 }
}
 
//連接處理
func handleConnection(conn net.Conn) {
 //緩沖區(qū),存儲(chǔ)被截?cái)嗟臄?shù)據(jù)
 tmpBuffer := make([]byte, 0)
 //接收解包
 readerChannel := make(chan []byte, 10000)
 go reader(readerChannel)
 
 buffer := make([]byte, 1024)
 for{
  n, err := conn.Read(buffer)
  if err != nil{
   Log(conn.RemoteAddr().String(), "connection error: ", err)
   return
  }
  tmpBuffer = protocol.Depack(append(tmpBuffer, buffer[:n]...))
  readerChannel <- tmpBuffer  //接收的信息寫(xiě)入通道
 }
 defer conn.Close()
}
 
//獲取通道數(shù)據(jù)
func reader(readerchannel chan []byte) {
 for{
  select {
  case data := <-readerchannel:
   Log(string(data))  //打印通道內(nèi)的信息
  }
 }
}
 
//日志處理
func Log(v ...interface{}) {
 log.Println(v...)
}
 
//錯(cuò)誤處理
func CheckErr(err error) {
 if err != nil {
  fmt.Fprintf(os.Stderr, "Fatal error: %s", err.Error())
  os.Exit(1)
 }
}

客戶端使用Enpack封裝要發(fā)送到服務(wù)端的信息后,寫(xiě)入連接conn中。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
/**
* MySocketProtocalClient
* @Author: Jian Junbo
* @Email: junbojian@qq.com
* @Create: 2017/9/14 15:23
* Copyright (c) 2017 Jian Junbo All rights reserved.
*
* Description:
*/
package main
import (
 "net"
 "time"
 "strconv"
 "protocol"
 "fmt"
 "os"
)
 
//發(fā)送100次請(qǐng)求
func send(conn net.Conn) {
 for i := 0; i < 100; i++ {
  session := GetSession()
  words := "{\"ID\":\""+strconv.Itoa(i)+"\",\"Session\":\""+session+"20170914165908\",\"Meta\":\"golang\",\"Content\":\"message\"}"
  conn.Write(protocol.Enpack([]byte(words)))
  fmt.Println(words)  //打印發(fā)送出去的信息
 }
 fmt.Println("send over")
 defer conn.Close()
}
//用當(dāng)前時(shí)間做識(shí)別。當(dāng)前時(shí)間的十進(jìn)制整數(shù)
func GetSession() string {
 gs1 := time.Now().Unix()
 gs2 := strconv.FormatInt(gs1, 10)
 return gs2
}
 
func main() {
 server := "localhost:7373"
 tcpAddr, err := net.ResolveTCPAddr("tcp4", server)
 if err != nil{
  fmt.Fprintf(os.Stderr, "Fatal error: %s", err.Error())
  os.Exit(1)
 }
 
 conn, err := net.DialTCP("tcp", nil, tcpAddr)
 if err != nil{
  fmt.Fprintf(os.Stderr, "Fatal error: %s", err.Error())
  os.Exit(1)
 }
 
 fmt.Println("connect success")
 send(conn)
}

補(bǔ)充:golang從0到1利用socket編程實(shí)現(xiàn)一個(gè)簡(jiǎn)單的http服務(wù)器

開(kāi)始編程

第一份代碼

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package main
import (
    "fmt"
    "net"
)
func accept_request_thread(conn net.Conn) {
    defer conn.Close()
    for {
        // 創(chuàng)建一個(gè)新切片, 用作保存數(shù)據(jù)的緩沖區(qū)
        buf := make([]byte, 1024)
        n, err := conn.Read(buf) // 從conn中讀取客戶端發(fā)送的數(shù)據(jù)內(nèi)容
        if err != nil {
            fmt.Printf("客戶端退出 err=%v\n", err)
            return
        }
        fmt.Printf(" 接受消息 %s\n", string(buf[:n]))
    }
}
func main() {
    listen, err := net.Listen("tcp", ":8888") // 創(chuàng)建用于監(jiān)聽(tīng)的 socket
    if err != nil {
        fmt.Println("listen err=", err)
        return
    }
    fmt.Println("監(jiān)聽(tīng)套接字,創(chuàng)建成功, 服務(wù)器開(kāi)始監(jiān)聽(tīng)。。。")
    defer listen.Close() // 服務(wù)器結(jié)束前關(guān)閉 listener
    // 循環(huán)等待客戶端來(lái)鏈接
    for {
        fmt.Println("阻塞等待客戶端來(lái)鏈接...")
        conn, err := listen.Accept() // 創(chuàng)建用戶數(shù)據(jù)通信的socket
        if err != nil {
            fmt.Println("Accept() err=", err)
        } else {
            fmt.Println("通信套接字,創(chuàng)建成功。。。")
        }
        // 這里準(zhǔn)備起一個(gè)協(xié)程,為客戶端服務(wù)
        go accept_request_thread(conn)
    }
}

瀏覽器發(fā)送一個(gè)get請(qǐng)求:

http://192.168.0.20:8888/api/camera/get_ptz?camera_id=1324566666789876543

服務(wù)端接受到的消息如下:

http://192.168.0.20:8888/api/camera/get_ptz?camera_id=1324566666789876543

Golang Socket Server自定義協(xié)議的簡(jiǎn)單實(shí)現(xiàn)方案

我們接下來(lái)的任務(wù)就是 解析這些字符串,從中獲取 當(dāng)前是什么方法,什么請(qǐng)求,參數(shù)是什么?

先定義一個(gè)小目標(biāo),獲取當(dāng)前是什么方法。

處理一個(gè)簡(jiǎn)單的get請(qǐng)求

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
package main
import (
    "encoding/json"
    "fmt"
    "log"
    "net"
    "strings"
)
func unimplemented(conn net.Conn){
    var buf string
    buf = "HTTP/1.0 501 Method Not Implemented\r\n"
    _, _ = conn.Write([]byte(buf))
    buf = "Server: httpd/0.1.0\r\n"
    _, _ = conn.Write([]byte(buf))
    buf = "Content-Type: text/html\r\n"
    _, _ = conn.Write([]byte(buf))
    buf = "\r\n"
    _, _ = conn.Write([]byte(buf))
    buf = "<HTML><HEAD><TITLE>Method Not Implemented\r\n"
    _, _ = conn.Write([]byte(buf))
    buf = "</TITLE></HEAD>\r\n"
    _, _ = conn.Write([]byte(buf))
    buf = "<BODY><P>HTTP request method not supported.\r\n"
    _, _ = conn.Write([]byte(buf))
    buf = "</BODY></HTML>\r\n"
    _, _ = conn.Write([]byte(buf))
}
func accept_request_thread(conn net.Conn) {
    defer conn.Close()
    var i int
    buf := make([]byte, 1024)
    n, err := conn.Read(buf) // 從conn中讀取客戶端發(fā)送的數(shù)據(jù)內(nèi)容
    if err != nil {
        fmt.Printf("客戶端退出 err=%v\n", err)
        return
    }
    // 獲取方法
    i = 0
    var method_bt strings.Builder
    for(i < n && buf[i] != ' '){
        method_bt.WriteByte(buf[i])
        i++;
    }
    method := method_bt.String()
    if(method != "GET"){
        unimplemented(conn)
        return
    }
    for(i < n && buf[i] == ' '){
        i++
    }
    //api/camera/get_ptz?camera_id=1324566666789876543
    var url_bt strings.Builder
    for(i < n && buf[i] != ' '){
        url_bt.WriteByte(buf[i])
        i++;
    }
    url := url_bt.String()
    if(method == "GET"){
        //url ---> /api/camera/get_ptz?camera_id=1324566666789876543
        // 跳到第一個(gè)?
        var path, query_string string
        j := strings.IndexAny(url, "?")
        if(j != -1){
            path = url[:j]
            if(j + 1 < len(url)){
                query_string = url[j+1:]
            }
        }else{
            path = url
        }
        fmt.Print(path + "請(qǐng)求已經(jīng)創(chuàng)建\t")
        resp := execute(path, query_string)// =1324566666789876543
        fmt.Println("返回", string(resp))
        header(conn, "application/json", len(resp));
        _ , err := conn.Write(resp)
        if(err != nil){
            fmt.Println(err)
        }
    }
}
//回應(yīng)客戶端必須先設(shè)置好head頭,瀏覽器才能解析
func header(conn net.Conn, content_type string , length int ) {
    var buf string
    buf = "HTTP/1.0 200 OK\r\n"
    _, _ = conn.Write([]byte(buf))
    buf = "Server: httpd/0.1.0\r\n"
    _, _ = conn.Write([]byte(buf))
    buf = "Content-Type: " + content_type + "\r\n"
    _, _ = conn.Write([]byte(buf))
    _, _ = fmt.Sscanf(buf, "Content-Length: %d\r\n", length)
    buf = "Content-Type: " + content_type + "\r\n"
    _, _ = conn.Write([]byte(buf))
    buf = "\r\n"
    _, _ = conn.Write([]byte(buf))
}
func execute(path string, query_string string) ([]byte) {
    query_params := make(map[string]string)
    parse_query_params(query_string, query_params)
    if("/api/camera/get_ptz" == path){
        /*
         * do something
         */
        camera_id := query_params["camera_id"]
        resp := make(map[string]interface{})
        resp["camera_id"] = camera_id
        resp["code"] = 200
        resp["msg"] = "ok"
        rs, err := json.Marshal(resp)
        if err != nil{
            log.Fatalln(err)
        }
        return rs
    }else if("get_abc" == path){
        /*
         * do something
         */
        return []byte("abcdcvfdswa")
    }
    return []byte("do't match")
}
/*map作為函數(shù)入?yún)⑹亲鳛橹羔樳M(jìn)行傳遞的
函數(shù)里面對(duì)map進(jìn)行修改時(shí),會(huì)同時(shí)修改源map的值,但是將map修改為nil時(shí),則達(dá)不到預(yù)期效果。*/
// camera_id=1324566666789876543&tt=%E5%88%9B%E5%BB%BA%E6%88%90%E5%8A%9F
func parse_query_params(query_string string, query_params map[string]string) {
    kvs := strings.Split(query_string, "&")
    if(len(kvs) == 0){
        return
    }
    for _, kv := range kvs {
        kv := strings.Split(kv, "=")
        if(len(kv) != 2){
            continue
        }
        query_params[kv[0]] = kv[1]
    }
}
func main() {
    listen, err := net.Listen("tcp", ":8888") // 創(chuàng)建用于監(jiān)聽(tīng)的 socket
    if err != nil {
        fmt.Println("listen err=", err)
        return
    }
    fmt.Println("監(jiān)聽(tīng)套接字,創(chuàng)建成功, 服務(wù)器開(kāi)始監(jiān)聽(tīng)。。。")
    defer listen.Close() // 服務(wù)器結(jié)束前關(guān)閉 listener
    // 循環(huán)等待客戶端鏈接
    for {
        fmt.Println("阻塞等待客戶端鏈接...")
        conn, err := listen.Accept() // 創(chuàng)建用戶數(shù)據(jù)通信的socket
        if err != nil {
            panic("Accept() err= " + err.Error())
        }
        // 這里準(zhǔn)備起一個(gè)協(xié)程,為客戶端服務(wù)
        go accept_request_thread(conn)
    }
}

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持服務(wù)器之家。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教。

原文鏈接:https://blog.csdn.net/lengyuezuixue/article/details/79213568

延伸 · 閱讀

精彩推薦
  • Golanggolang如何使用struct的tag屬性的詳細(xì)介紹

    golang如何使用struct的tag屬性的詳細(xì)介紹

    這篇文章主要介紹了golang如何使用struct的tag屬性的詳細(xì)介紹,從例子說(shuō)起,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看...

    Go語(yǔ)言中文網(wǎng)11352020-05-21
  • GolangGolang通脈之?dāng)?shù)據(jù)類型詳情

    Golang通脈之?dāng)?shù)據(jù)類型詳情

    這篇文章主要介紹了Golang通脈之?dāng)?shù)據(jù)類型,在編程語(yǔ)言中標(biāo)識(shí)符就是定義的具有某種意義的詞,比如變量名、常量名、函數(shù)名等等,Go語(yǔ)言中標(biāo)識(shí)符允許由...

    4272021-11-24
  • Golanggo語(yǔ)言制作端口掃描器

    go語(yǔ)言制作端口掃描器

    本文給大家分享的是使用go語(yǔ)言編寫(xiě)的TCP端口掃描器,可以選擇IP范圍,掃描的端口,以及多線程,有需要的小伙伴可以參考下。 ...

    腳本之家3642020-04-25
  • Golanggolang json.Marshal 特殊html字符被轉(zhuǎn)義的解決方法

    golang json.Marshal 特殊html字符被轉(zhuǎn)義的解決方法

    今天小編就為大家分享一篇golang json.Marshal 特殊html字符被轉(zhuǎn)義的解決方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧 ...

    李浩的life12792020-05-27
  • GolangGolang中Bit數(shù)組的實(shí)現(xiàn)方式

    Golang中Bit數(shù)組的實(shí)現(xiàn)方式

    這篇文章主要介紹了Golang中Bit數(shù)組的實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧...

    天易獨(dú)尊11682021-06-09
  • Golanggolang的httpserver優(yōu)雅重啟方法詳解

    golang的httpserver優(yōu)雅重啟方法詳解

    這篇文章主要給大家介紹了關(guān)于golang的httpserver優(yōu)雅重啟的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,...

    helight2992020-05-14
  • Golanggolang 通過(guò)ssh代理連接mysql的操作

    golang 通過(guò)ssh代理連接mysql的操作

    這篇文章主要介紹了golang 通過(guò)ssh代理連接mysql的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧...

    a165861639710342021-03-08
  • Golanggo日志系統(tǒng)logrus顯示文件和行號(hào)的操作

    go日志系統(tǒng)logrus顯示文件和行號(hào)的操作

    這篇文章主要介紹了go日志系統(tǒng)logrus顯示文件和行號(hào)的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧...

    SmallQinYan12302021-02-02
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 人人干在线 | 国产精品射 | av一区二区三区四区 | 性做久久久 | 男人的天堂中文字幕 | 成人片网址 | 一级黄色在线观看 | 国外精品久久久蜜桃免费全文阅读 | av一区二区在线观看 | 国产精品毛片久久久久久久明星 | 韩日一区 | 亚色在线| 亚洲精品综合中文字幕 | 91av免费在线观看 | 久热久热 | 动漫泳衣美女 | 久久久精品影院 | 亚洲一区中文 | 一级黄免费看 | 午夜电影| 91丝袜 | 国产福利视频在线观看 | 国产在线中文字幕 | 国产精彩视频 | 日韩在线精品视频 | 青青草91青娱盛宴国产 | 国产激情在线观看 | 国产欧美自拍 | 性天堂 | 亚洲欧美视频一区 | 免费a视频 | 一级在线观看视频 | 亚洲欧美日韩精品久久奇米色影视 | 亚洲精品资源在线观看 | 免费成人一级片 | 亚洲国产精品久久久 | 亚洲视频在线观看中文字幕 | www.操操操 | 精品日韩视频 | 亚洲欧美中文字幕 | 国内精品一区二区三区 |