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

Netty 是如何解決半包和粘包問題?

網(wǎng)絡(luò)
Netty 是一個高性能、異步事件驅(qū)動的網(wǎng)絡(luò)應(yīng)用框架,廣泛應(yīng)用于各種網(wǎng)絡(luò)通信場景。這篇文章,我們將詳細(xì)分析 Netty 是如何解決半包和粘包問題。

Netty 是一個高性能、異步事件驅(qū)動的網(wǎng)絡(luò)應(yīng)用框架,廣泛應(yīng)用于各種網(wǎng)絡(luò)通信場景。這篇文章,我們將詳細(xì)分析 Netty 是如何解決半包和粘包問題。

一、什么是半包和粘包?

1.半包問題

半包問題是指一個完整的應(yīng)用層消息被分成多個 TCP 數(shù)據(jù)包發(fā)送,接收端在一次讀取操作中只接收到消息的一部分。

例如,發(fā)送端發(fā)送了一條 100 字節(jié)的消息,但由于網(wǎng)絡(luò)原因,這條消息被拆分成了兩個 TCP 數(shù)據(jù)包,一個 60 字節(jié),另一個 40 字節(jié)。接收端可能在第一次讀取時只接收到前 60 字節(jié)的數(shù)據(jù),剩下的 40 字節(jié)需要在后續(xù)的讀取操作中才能接收到。

2.粘包問題

粘包問題是指多個應(yīng)用層消息在傳輸過程中被粘在一起,接收端在一次讀取操作中接收到大于 1個消息的情況。

例如,發(fā)送端發(fā)送了兩條消息,每條 50 字節(jié),但接收端在一次讀取操作中收到了 80 字節(jié)的數(shù)據(jù),超過了 1條消息的內(nèi)容。

3.產(chǎn)生原因

產(chǎn)生半包和粘包問題主要是以下 3個原因:

  • TCP 的流式特性:TCP 是面向字節(jié)流的協(xié)議,沒有消息邊界的概念,它保證數(shù)據(jù)的順序和可靠性,但不保證每次發(fā)送的數(shù)據(jù)對應(yīng)每次接收的數(shù)據(jù)。
  • 網(wǎng)絡(luò)狀況:網(wǎng)絡(luò)的擁塞、延遲、抖動等因素可能導(dǎo)致數(shù)據(jù)包的拆分和重組。
  • 操作系統(tǒng)和緩沖區(qū):操作系統(tǒng) TCP/IP 協(xié)議棧和應(yīng)用程序的緩沖區(qū)大小也會影響數(shù)據(jù)的讀取方式。

4.示例

假設(shè)發(fā)送端發(fā)送了兩條消息:

  • 消息1:Hello
  • 消息2:World

在半包情況下,接收端可能會這樣接收:

  • 第一次讀取:Hel
  • 第二次讀取:loWo
  • 第三次讀取:rld

在粘包情況下,接收端可能會這樣接收:

  • 第一次讀取:HelloWor
  • 第二次讀取:ld

二、解決方案

1.基于固定長度的解碼器

基于固定長度的解碼器是指發(fā)消息時,每條消息的長度固定,讀消息時也通過固定長度來讀取消息,從而解決半包和粘包問題。

(1) 實現(xiàn)方式

Netty 提供了 FixedLengthFrameDecoder 類來實現(xiàn)這一功能,核心源碼如下:

public class FixedLengthFrameDecoder extends ByteToMessageDecoder {
private final int frameLength;

    public FixedLengthFrameDecoder(int frameLength) {
        this.frameLength = frameLength;
    }

    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
        while (in.readableBytes() >= frameLength) {
            ByteBuf buf = in.readBytes(frameLength);
            out.add(buf);
        }
    }
}

(2) 注意點

使用定長幀需要注意以下幾點:

  • 固定長度:消息長度必須是固定的,發(fā)送端需要確保消息長度一致。如果長度超出固定長度,解包時消息就會錯位,如果消息不足固定長度,需要使用填充字符補(bǔ)齊。
  • 填充字符:選擇合適的填充字符(如空格)來補(bǔ)齊消息長度,接收端在處理時需要去除這些填充字符。

(3) 優(yōu)點

  • 簡單易實現(xiàn):實現(xiàn)起來非常簡單,不需要額外的頭部信息或分隔符。
  • 解析效率高:由于每個消息長度固定,接收端解析時只需按照固定長度讀取。

(4) 缺點

  • 不靈活:消息長度固定,可能會造成空間浪費(如果消息長度較短)或不足(如果消息長度較長)。
  • 適用場景有限:適用于固定格式和長度的協(xié)議,不適用于可變長度消息的場景。

(5) 示例

下面我們通過一個示例來展示使用定長幀是如何解決半包粘包問題的。

發(fā)送端,確保每個消息的長度固定。如果實際消息長度不足,可以使用填充字符(如空格)來補(bǔ)齊。

public class FixedLengthFrameSender {

    private static final int FRAME_LENGTH = 10; // 固定消息長度

    public static void send(Channel channel, String message) {
        // 確保消息長度不超過固定長度
        if (message.length() > FRAME_LENGTH) {
            throw new IllegalArgumentException("Message too long");
        }
        // 使用空格填充消息到固定長度
        String paddedMessage = String.format("%-" + FRAME_LENGTH + "s", message);
        
        // 將消息轉(zhuǎn)換為字節(jié)數(shù)組并發(fā)送
        ByteBuf buffer = Unpooled.copiedBuffer(paddedMessage.getBytes());
        channel.writeAndFlush(buffer);
    }
}

接收端,使用 Netty 提供的 FixedLengthFrameDecoder 解碼器來處理固定長度的消息。

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.FixedLengthFrameDecoder;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;

public class FixedLengthFrameReceiver {
    private static final int FRAME_LENGTH = 10; // 固定消息長度

    public static void main(String[] args) throws Exception {
        NioEventLoopGroup bossGroup = new NioEventLoopGroup(1);
        NioEventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(bossGroup, workerGroup)
             .channel(NioServerSocketChannel.class)
             .childHandler(new ChannelInitializer<SocketChannel>() {
                 @Override
                 public void initChannel(SocketChannel ch) throws Exception {
                     ChannelPipeline p = ch.pipeline();
                     // 添加定長幀解碼器
                     p.addLast(new FixedLengthFrameDecoder(FRAME_LENGTH));
                     // 添加自定義處理器
                     p.addLast(new FixedLengthFrameHandler());
                 }
             });
            // 啟動服務(wù)器
            b.bind(8888).sync().channel().closeFuture().sync();
        } finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }

    public static class FixedLengthFrameHandler extends ChannelInboundHandlerAdapter {
        @Override
        public void channelRead(ChannelHandlerContext ctx, Object msg) {
            ByteBuf in = (ByteBuf) msg;
            byte[] receivedBytes = new byte[in.readableBytes()];
            in.readBytes(receivedBytes);
            String receivedMsg = new String(receivedBytes).trim(); // 去除填充字符
            System.out.println("Received: " + receivedMsg);
        }
        @Override
        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
            cause.printStackTrace();
            ctx.close();
        }
    }
}

2.基于換行符解碼器

3.自定義分隔符解碼器

基于換行符解碼器和自定義分隔符解碼器(比如 特殊字符)來劃分消息邊界,從而解決半包和粘包問題,使用者可以根據(jù)自己的需求靈活確定分隔符。

(1) 實現(xiàn)方式

Netty 提供了 DelimiterBasedFrameDecoder 類來實現(xiàn)這一功能,核心源碼如下:

public DelimiterBasedFrameDecoder(
        int maxFrameLength, boolean stripDelimiter, boolean failFast, ByteBuf... delimiters) {
   validateMaxFrameLength(maxFrameLength);
   ObjectUtil.checkNonEmpty(delimiters, "delimiters");

   if (isLineBased(delimiters) && !isSubclass()) {
      lineBasedDecoder = new LineBasedFrameDecoder(maxFrameLength, stripDelimiter, failFast);
      this.delimiters = null;
   } else {
      this.delimiters = new ByteBuf[delimiters.length];
      for (int i = 0; i < delimiters.length; i ++) {
         ByteBuf d = delimiters[i];
         validateDelimiter(d);
         this.delimiters[i] = d.slice(d.readerIndex(), d.readableBytes());
      }
      lineBasedDecoder = null;
   }
   this.maxFrameLength = maxFrameLength;
   this.stripDelimiter = stripDelimiter;
   this.failFast = failFast;
}

(2) 注意點

  • 分隔符選擇:選擇一個不會出現(xiàn)在消息內(nèi)容中的分隔符(如換行符 \n 或特定字符 |)。
  • 消息格式:發(fā)送端在每個消息的末尾添加分隔符,確保接收端能夠正確解析消息邊界。

(3) 優(yōu)點

  • 靈活性高:可以處理可變長度的消息。
  • 實現(xiàn)相對簡單:只需在消息末尾添加特定的分隔符,接收端根據(jù)分隔符拆分消息。

(4) 缺點

  • 分隔符沖突:如果消息內(nèi)容中包含分隔符,可能導(dǎo)致解析錯誤,需要對消息內(nèi)容進(jìn)行轉(zhuǎn)義處理。
  • 解析效率低:需要掃描整個數(shù)據(jù)流尋找分隔符,效率較低。

(5) 示例

下面我們通過一個示例來展示使用分隔符是如何解決半包粘包問題的。

發(fā)送端,確保每個消息以特定的分隔符結(jié)尾。常用的分隔符包括換行符(\n)、特定字符(如 |)等。

public class DelimiterBasedFrameSender {

    private static final String DELIMITER = "\n"; // 分隔符

    public static void send(Channel channel, String message) {
        // 在消息末尾添加分隔符
        String delimitedMessage = message + DELIMITER;
        
        // 將消息轉(zhuǎn)換為字節(jié)數(shù)組并發(fā)送
        ByteBuf buffer = Unpooled.copiedBuffer(delimitedMessage.getBytes());
        channel.writeAndFlush(buffer);
    }
}

接收端,使用 Netty 提供的 DelimiterBasedFrameDecoder 解碼器來處理以分隔符結(jié)尾的消息。

import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.DelimiterBasedFrameDecoder;
import io.netty.handler.codec.string.StringDecoder;

public class DelimiterBasedFrameReceiver {

    private static final String DELIMITER = "\n"; // 分隔符
    private static final int MAX_FRAME_LENGTH = 1024; // 最大幀長度

    public static void main(String[] args) throws Exception {
        NioEventLoopGroup bossGroup = new NioEventLoopGroup(1);
        NioEventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(bossGroup, workerGroup)
             .channel(NioServerSocketChannel.class)
             .childHandler(new ChannelInitializer<SocketChannel>() {
                 @Override
                 public void initChannel(SocketChannel ch) throws Exception {
                     ChannelPipeline p = ch.pipeline();
                     // 添加分隔符解碼器
                     ByteBuf delimiter = Unpooled.copiedBuffer(DELIMITER.getBytes());
                     p.addLast(new DelimiterBasedFrameDecoder(MAX_FRAME_LENGTH, delimiter));
                     // 添加字符串解碼器
                     p.addLast(new StringDecoder());
                     // 添加自定義處理器
                     p.addLast(new DelimiterBasedFrameHandler());
                 }
             });

            // 啟動服務(wù)器
            b.bind(8888).sync().channel().closeFuture().sync();
        } finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }

    public static class DelimiterBasedFrameHandler extends ChannelInboundHandlerAdapter {
        @Override
        public void channelRead(ChannelHandlerContext ctx, Object msg) {
            String receivedMsg = (String) msg;
            System.out.println("Received: " + receivedMsg);
        }

        @Override
        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
            cause.printStackTrace();
            ctx.close();
        }
    }
}

4.基于長度字段的解碼器

基于長度字段的解碼器是指在消息頭部添加長度字段,指示消息的總長度。

(1) 實現(xiàn)方式

Netty 提供了 LengthFieldBasedFrameDecoder 類來實現(xiàn)這一功能,核心源碼如下:

public class LengthFieldBasedFrameDecoder extends ByteToMessageDecoder {
private final int maxFrameLength;
private final int lengthFieldOffset;
private final int lengthFieldLength;

    public LengthFieldBasedFrameDecoder(int maxFrameLength, int lengthFieldOffset, int lengthFieldLength) {
        this.maxFrameLength = maxFrameLength;
        this.lengthFieldOffset = lengthFieldOffset;
        this.lengthFieldLength = lengthFieldLength;
    }

    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
        if (in.readableBytes() < lengthFieldOffset + lengthFieldLength) {
            return;
        }

        in.markReaderIndex();
        int length = in.getInt(in.readerIndex() + lengthFieldOffset);
        if (in.readableBytes() < lengthFieldOffset + lengthFieldLength + length) {
            in.resetReaderIndex();
            return;
        }

        in.skipBytes(lengthFieldOffset + lengthFieldLength);
        ByteBuf frame = in.readBytes(length);
        out.add(frame);
    }
}

(2) 關(guān)鍵點

長度字段位置:長度字段通常位于消息的頭部,用于指示消息的總長度。

解碼器參數(shù):

  • maxFrameLength:消息的最大長度,防止內(nèi)存溢出。
  • lengthFieldOffset:長度字段在消息中的偏移量。
  • lengthFieldLength:長度字段的字節(jié)數(shù)(通常為 4 字節(jié))。
  • lengthAdjustment:長度調(diào)整值,如果長度字段不包含消息頭的長度,需要進(jìn)行調(diào)整。
  • initialBytesToStrip:解碼后跳過的字節(jié)數(shù),通常為長度字段的長度。

(3) 優(yōu)點

  • 靈活性高:支持可變長度的消息。
  • 解析效率高:通過長度字段可以直接讀取完整消息,無需掃描整個數(shù)據(jù)流。

(4) 缺點

  • 實現(xiàn)復(fù)雜:需要在消息頭部添加長度字段,接收端需要解析頭部信息。
  • 額外開銷:消息頭部的長度字段會增加一些額外的字節(jié)數(shù)。

(5) 示例

下面我們通過一個示例來展示使用長度字段是如何解決半包粘包問題的。

發(fā)送端,確保每個消息在發(fā)送前都包含長度字段。長度字段通常放在消息的頭部,用于指示消息的總長度。

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;

public class LengthFieldBasedFrameSender {

    public static void send(Channel channel, String message) {
        // 將消息轉(zhuǎn)換為字節(jié)數(shù)組
        byte[] messageBytes = message.getBytes();
        int messageLength = messageBytes.length;

        // 創(chuàng)建一個 ByteBuf 來存儲長度字段和消息內(nèi)容
        ByteBuf buffer = Unpooled.buffer(4 + messageLength);

        // 寫入長度字段(4 字節(jié),表示消息長度)
        buffer.writeInt(messageLength);

        // 寫入消息內(nèi)容
        buffer.writeBytes(messageBytes);

        // 發(fā)送消息
        channel.writeAndFlush(buffer);
    }
}

接收端,使用 Netty 提供的 LengthFieldBasedFrameDecoder 解碼器來處理包含長度字段的消息。

import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.codec.string.StringDecoder;

public class LengthFieldBasedFrameReceiver {

    private static final int MAX_FRAME_LENGTH = 1024; // 最大幀長度

    public static void main(String[] args) throws Exception {
        NioEventLoopGroup bossGroup = new NioEventLoopGroup(1);
        NioEventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(bossGroup, workerGroup)
             .channel(NioServerSocketChannel.class)
             .childHandler(new ChannelInitializer<SocketChannel>() {
                 @Override
                 public void initChannel(SocketChannel ch) throws Exception {
                     ChannelPipeline p = ch.pipeline();
                     // 添加長度字段解碼器
                     p.addLast(new LengthFieldBasedFrameDecoder(
                         MAX_FRAME_LENGTH, 0, 4, 0, 4));
                     // 添加字符串解碼器
                     p.addLast(new StringDecoder());
                     // 添加自定義處理器
                     p.addLast(new LengthFieldBasedFrameHandler());
                 }
             });

            // 啟動服務(wù)器
            b.bind(8888).sync().channel().closeFuture().sync();
        } finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }

    public static class LengthFieldBasedFrameHandler extends ChannelInboundHandlerAdapter {
        @Override
        public void channelRead(ChannelHandlerContext ctx, Object msg) {
            String receivedMsg = (String) msg;
            System.out.println("Received: " + receivedMsg);
        }

        @Override
        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
            cause.printStackTrace();
            ctx.close();
        }
    }
}

5. 自定義解碼器

如果上述 Netty提供的方案無法滿足業(yè)務(wù)需求的話,Netty還提供了一個擴(kuò)展點,使用者可以通過自定義解碼器來處理消息,

(1) 實現(xiàn)方式

例如,自定義頭部信息來表示消息長度或結(jié)束標(biāo)志,示例代碼如下:

public class CustomProtocolDecoder extends ByteToMessageDecoder {
    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
        // 根據(jù)自定義協(xié)議解析消息
        if (in.readableBytes() < 4) {
            return;
        }

        in.markReaderIndex();
        int length = in.readInt();
        if (in.readableBytes() < length) {
            in.resetReaderIndex();
            return;
        }

        ByteBuf frame = in.readBytes(length);
        out.add(frame);
    }
}

(2) 優(yōu)點

  • 高度靈活:可以根據(jù)具體需求設(shè)計協(xié)議,適應(yīng)各種復(fù)雜場景。
  • 功能豐富:可以在自定義協(xié)議中添加其他信息(如校驗和、序列號等),增強(qiáng)協(xié)議的功能和可靠性。

(3) 缺點

  • 實現(xiàn)復(fù)雜:設(shè)計和實現(xiàn)自定義協(xié)議需要更多的工作量。
  • 維護(hù)成本高:自定義協(xié)議可能需要更多的維護(hù)和更新工作。

總結(jié)

本文我們分析了產(chǎn)生半包和粘包的原因以及在Netty中的 5種解決方案:

  • 基于固定長度解碼器
  • 基于換行符解碼器
  • 自定義分隔符解碼器
  • 基于長度字段解碼器
  • 自定義解碼器

通過學(xué)習(xí)這些內(nèi)容,我們不僅掌握了半包和粘包問題的理論知識,同時學(xué)會了多種解決方法的具體實現(xiàn)。

責(zé)任編輯:趙寧寧 來源: 猿java
相關(guān)推薦

2019-10-25 00:32:12

TCP粘包Netty

2021-07-15 10:35:16

NettyTCPJava

2024-06-03 08:09:46

2022-08-01 07:07:15

粘包半包封裝

2019-10-24 07:35:13

TCP粘包Netty

2020-01-06 15:23:41

NettyTCP粘包

2025-04-10 10:15:30

2021-01-13 10:18:29

SocketNetty粘包

2019-10-17 11:06:32

TCP粘包通信協(xié)議

2021-01-30 19:35:44

HDFS單點Hadoop

2012-09-05 11:09:15

SELinux操作系統(tǒng)

2019-08-15 07:43:38

TCP網(wǎng)絡(luò)協(xié)議丟包

2018-05-17 09:40:56

區(qū)塊鏈身份識別身份驗證

2025-07-29 01:20:00

失效InnoDB存儲

2022-09-07 07:05:25

跨域問題安全架構(gòu)

2010-04-29 17:46:31

Oracle死鎖

2023-11-28 08:00:00

SpringJava

2023-02-15 07:03:41

跨域問題面試安全

2012-05-30 10:06:56

虛擬化UC統(tǒng)一通信

2017-07-20 07:30:16

大數(shù)據(jù)數(shù)據(jù)互聯(lián)網(wǎng)
點贊
收藏

51CTO技術(shù)棧公眾號

亚洲直播在线一区| 最近2019年中文视频免费在线观看 | 久久国产福利国产秒拍| 日韩中文在线不卡| 国产精品久久久久久久av福利| 黄色片网站在线播放| 91麻豆精品成人一区二区| 国产精品迅雷| 国产精品电影一区二区| 99久久精品免费看国产一区二区三区 | 欧美一区二区三区网站| 国产精品久久久久久久免费观看 | 四虎在线观看| 久久国产精品99久久久久久老狼| 久久久久亚洲精品国产| 91激情视频在线观看| 欧美专区一区| 欧美在线你懂得| 国产va亚洲va在线va| 第九色区av在线| 国产成人在线看| 国产成人精品视频在线观看| 草视频在线观看| 加勒比久久综合| 亚洲成人激情在线| 奇米影视四色在线| 中文字幕在线视频网站| 一区二区三区四区亚洲| 亚洲国产日韩综合一区| 天天操天天操天天操| 国产一区二区看久久| 国产成人精品a视频一区www| 国产精品自拍视频一区| 一级毛片免费高清中文字幕久久网| 精品亚洲夜色av98在线观看 | 九九99久久精品在免费线bt| 在线观看91视频| 欧美网站免费观看| 不卡的av影片| 亚洲一区在线视频观看| 精品久久免费观看| aaa在线观看| 久久久青草青青国产亚洲免观| 成人国产1314www色视频| 国产精品自拍电影| 看片的网站亚洲| 国产精品久久久久久久久久久新郎 | 精品美女久久久| 日韩精品在线免费观看| 中文字幕 日本| 哺乳挤奶一区二区三区免费看| 在线播放视频一区| 一区二区在线免费看| 久久xxx视频| 欧洲一区在线电影| av无码精品一区二区三区| 免费福利视频一区二区三区| 欧美日韩亚洲成人| 男人天堂999| 日产福利视频在线观看| 精品国产福利在线| 欧美黄网站在线观看| 在线免费av资源| 色婷婷激情一区二区三区| 国产91在线视频观看| 高潮一区二区| 在线观看一区二区视频| 国产精品人人爽人人爽| 欧美不卡高清一区二区三区| 在线观看日韩av先锋影音电影院| 三级a在线观看| 色狠狠一区二区三区| 666欧美在线视频| 亚洲熟女乱综合一区二区| 日韩精品一区国产| 亚洲国产成人av在线| 噜噜噜在线视频| 久久av影视| 日韩中文字幕av| 国产传媒免费在线观看| 欧美全黄视频| 91福利视频在线观看| 性色av免费观看| 久热成人在线视频| av免费观看久久| 天天干,天天操,天天射| 国产午夜亚洲精品理论片色戒| 新呦u视频一区二区| 菠萝菠萝蜜在线视频免费观看| 亚洲综合区在线| 国产淫片免费看| 91麻豆精品国产综合久久久| 欧美成人女星排行榜| 在线 丝袜 欧美 日韩 制服| 色琪琪久久se色| 久久久久久亚洲精品| 蜜臀精品一区二区三区| 国产在线视视频有精品| 国产精品一区二区三区在线观| 欧美3p视频在线观看| 亚洲免费观看高清完整版在线| 国产一区二区视频播放| 日韩成人免费av| 亚洲成在人线av| 国产探花视频在线播放| 亚洲天堂成人| 国产精品视频一区国模私拍| 丰满人妻一区二区三区无码av| 久久精品亚洲精品国产欧美kt∨| 精品少妇人妻av一区二区| 在线观看特色大片免费视频| 欧美一区二区三区在线观看视频| 久久亚洲AV成人无码国产野外 | 国产一区二区三区四区福利| 欧美丰满熟妇bbbbbb| 午夜在线播放视频欧美| 亚洲最大激情中文字幕| 国产中文字幕在线| 亚洲高清在线视频| 伊人免费视频二| 精品免费视频| 9.1国产丝袜在线观看 | 青娱乐在线视频免费观看| 久久亚洲精品伦理| 国产精品一区二区在线观看| 黄色精品免费看| 91国偷自产一区二区使用方法| 国产成人精品一区二区三区在线观看| 不卡日本视频| 欧美一二三视频| 日本精品999| 亚洲精品视频观看| 污视频网址在线观看| 九色精品国产蝌蚪| 91av视频在线免费观看| www日本视频| 亚洲同性gay激情无套| 奇米影视四色在线| 日韩电影免费在线观看| 国产激情999| 极品美乳网红视频免费在线观看 | 91成人综合网| 国产美女精品视频免费播放软件| 中文字幕精品网| 中文字幕日本视频| 国产欧美视频一区二区| 久久网站免费视频| 婷婷综合一区| 日本精品视频网站| 精品乱码一区二区三四区视频| 午夜精品久久一牛影视| 成人在线电影网站| 一道本一区二区| 国产三级精品在线不卡| 51精品在线| 亚洲精品国产精品乱码不99按摩 | 欧美三级特黄| 成人片在线免费看| 丁香影院在线| 亚洲国产小视频在线观看| 日韩精品久久久久久久| 99久久精品国产毛片| 亚洲 欧美 日韩 国产综合 在线| 大型av综合网站| 26uuu国产精品视频| 性感美女一级片| 色先锋久久av资源部| 国产精品国产三级国产专业不| 日本欧洲一区二区| 一区二区三区观看| 日本在线成人| 高清欧美性猛交| 日本1级在线| 欧美在线观看视频一区二区三区| 日韩不卡av在线| 精品中文av资源站在线观看| 400部精品国偷自产在线观看| 日韩欧美中文字幕一区二区三区| 色综合老司机第九色激情| 开心激情综合网| 色婷婷综合五月| 中文字幕乱码av| 国产91在线看| 欧美 日韩精品| 成人精品电影| 51国偷自产一区二区三区| 精品精品导航| 亚洲欧美日韩视频一区| 国产原创中文av| 亚洲一区二区av在线| 久久精品国产亚洲av麻豆| 美女性感视频久久| 久久免费少妇高潮久久精品99| 国产人妻黑人一区二区三区| 亚洲国内自拍| 亚洲国产婷婷香蕉久久久久久99| 日本在线视频一区二区三区| 日本欧美一二三区| 国产三级在线播放| 精品香蕉一区二区三区| 国产精品久久久久久免费播放| 亚洲一区二区综合| 最新中文字幕av| 成人网男人的天堂| 日韩av在线中文| 亚洲永久免费| 日本一道在线观看| 国产精品一在线观看| 成人在线观看av| 不卡亚洲精品| 538国产精品视频一区二区| 日韩毛片久久久| 日韩电影视频免费| 国产黄色小视频在线观看| 色综合视频在线观看| 国产va在线播放| 中文字幕精品—区二区四季| 中文字幕a在线观看| 精久久久久久久久久久| 国产女女做受ⅹxx高潮| 亚洲天堂久久| 大片在线观看网站免费收看| 精品国产一区二区三区四区| 国内精品视频免费| 97se亚洲国产一区二区三区| 国产精品嫩草影院一区二区| 色偷偷色偷偷色偷偷在线视频| 精品国产一区二区三区在线观看| 久久久久久久影视| 日韩国产欧美精品在线| 狠狠躁日日躁夜夜躁av| 日韩欧美电影一区| 国产精品探花视频| 欧美日韩一区二区三区高清| 高清乱码免费看污| 精品久久久久久久久中文字幕| 欧美黄色一级网站| 亚洲欧美日韩在线不卡| 国内毛片毛片毛片毛片毛片| 国产欧美综合在线| 3d动漫精品啪啪一区二区下载| www.亚洲色图| 国产二级一片内射视频播放 | 亚洲电影在线播放| 青娱乐免费在线视频| 亚洲欧美日韩在线| 欧美黑人猛猛猛| 亚洲欧美激情小说另类| 熟女少妇a性色生活片毛片| 国产精品毛片无遮挡高清| 少妇精品无码一区二区免费视频| 26uuu色噜噜精品一区| 亚洲最大的黄色网| 91在线精品一区二区| 97人妻精品一区二区三区免| 99这里只有精品| 精品中文字幕在线播放| 99re66热这里只有精品3直播| 欧美双性人妖o0| 91免费看视频| 六月婷婷七月丁香| 91偷拍与自偷拍精品| 日韩人妻一区二区三区| 国产欧美中文在线| 国产精品视频一区二区在线观看| 中文字幕一区二区三区在线观看| 在线日韩国产网站| 一区二区三区四区视频精品免费| 青青草原免费观看| 亚洲大片一区二区三区| 亚洲午夜18毛片在线看| 欧美亚洲禁片免费| 97超碰中文字幕| 日韩三级中文字幕| 色网站免费观看| 亚洲色在线视频| 亚洲欧美视频一区二区| 欧美刺激性大交免费视频| ****av在线网毛片| 国产成人午夜视频网址| 亚洲国产综合在线观看| 国产成人av一区二区三区| 欧美三级电影在线| 午夜精品视频在线观看一区二区| 国产精品久久天天影视| 欧美a级免费视频| 99国产精品99久久久久久粉嫩| 精品久久久久av| 精品一区二区三区免费播放 | 欧美影院在线| 开心色怡人综合网站| 欧美va久久久噜噜噜久久| 伊人久久在线观看| 久久精品人人| 男插女视频网站| 久久网站热最新地址| 一区二区三区在线播放视频| 亚洲国产一区视频| 不卡av电影在线| 日韩精品一区二区三区在线观看 | 日韩五码电影| 久久精品二区| 91精品高清| 亚洲熟妇av一区二区三区| 国产一区二区不卡在线| 波多野结衣先锋影音| 亚洲色图丝袜美腿| 99久久久无码国产精品免费蜜柚| 欧美一区二区三区在线视频| 毛片网站在线| 久久人91精品久久久久久不卡| 高清在线一区| 精品欧美日韩在线| 仙踪林久久久久久久999| 三级4级全黄60分钟| 风间由美性色一区二区三区| 国产一级淫片久久久片a级| 午夜久久久久久久久久一区二区| 一区二区国产欧美| 亚洲人午夜精品免费| a天堂资源在线| 亚洲xxx自由成熟| 欧美一区二区三| 成人在线免费观看av| 国产成人在线视频网站| 登山的目的在线| 在线精品视频免费观看| 视频国产在线观看| 性色av一区二区三区在线观看| 2019中文亚洲字幕| 亚洲一区二区三区乱码| 久久香蕉精品| 国产精品毛片一区二区| 精品久久久久久| 免费国产精品视频| 欧美精品第一页在线播放| 国产精品中文| 成人性做爰片免费视频| 久久国产视频网| 国产精品18在线| 欧美影视一区二区三区| 精品久久av| 国产成人精品久久久| 精品久久电影| 欧美精品aaaa| 国产亚洲欧美一区在线观看| 久久国产视频精品| 日韩精品视频在线观看免费| 欧美xxxhd| 免费av一区二区三区| 久久精品伊人| 中文字幕免费在线看线人动作大片| 色婷婷国产精品综合在线观看| 免费在线稳定资源站| 日本久久久久亚洲中字幕| 欧美日韩播放| 99热这里只有精品在线播放| 国产精品午夜电影| 一道本无吗一区| www欧美日韩| 日韩高清一区| 免费拍拍拍网站| 99精品视频一区二区| 特级做a爱片免费69| 亚洲天堂网在线观看| 国产一区影院| 99久热在线精品视频| 成人免费观看av| 国产一级片毛片| 丝袜一区二区三区| 欧美黄色一级| 成年人视频观看| 国产欧美精品日韩区二区麻豆天美| 在线观看国产小视频| 久久99久久99精品免观看粉嫩| 超碰成人福利| 久久精品午夜福利| 1024精品合集| 日韩一级片免费看| 日韩美女视频免费在线观看| 91视频综合| 污污免费在线观看| 91九色02白丝porn| 超碰在线免费播放| 久久亚洲午夜电影| 麻豆精品国产91久久久久久| 亚洲av无码一区二区三区在线| 亚洲第一精品夜夜躁人人爽| 666av成人影院在线观看| 一区二区三区在线观看www| 国产成人亚洲综合a∨婷婷 | av软件在线观看| 精品久久久久久一区| 美女脱光内衣内裤视频久久网站 | 黄色免费看视频| 欧美性猛交xxxxxx富婆| 国产盗摄在线视频网站| 日韩免费一区二区三区| 国产91精品一区二区| 日本黄色中文字幕|