精品欧美一区二区三区在线观看 _久久久久国色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ù)棧公眾號

香蕉久久国产| 久久97精品| 亚洲黄色片在线观看| 91久久精品在线| 免看一级a毛片一片成人不卡| 国产欧美自拍一区| 色综合久久88色综合天天6| 一本一本a久久| 人人妻人人澡人人爽人人欧美一区| 免费一区视频| 久久天天躁狠狠躁夜夜躁2014 | 久久电影tv| 国产精品久99| 久久99精品久久久久子伦| 日韩不卡高清视频| 欧美亚洲不卡| 在线观看久久av| 精品少妇人妻av一区二区三区| 欧美va在线观看| 亚洲一区二区三区国产| 少妇特黄a一区二区三区| 成人午夜免费在线观看| 麻豆久久一区二区| 97在线视频精品| 欧美国产日韩在线观看成人| 深爱激情久久| 亚洲高清在线观看| 亚洲AV无码久久精品国产一区| 忘忧草在线www成人影院| 亚洲国产aⅴ成人精品无吗| 自拍偷拍99| 国产精品影院在线| a在线播放不卡| yy111111少妇影院日韩夜片| 一区二区三区精彩视频| 日韩高清在线观看| 热久久免费视频精品| 久久精品女人毛片国产| 欧美激情日韩| 久久中文字幕国产| 日本爱爱小视频| 大胆日韩av| 亚洲天堂2020| 制服 丝袜 综合 日韩 欧美| 免费短视频成人日韩| 亚洲国产欧美一区二区丝袜黑人| 亚洲美女精品视频| 亚洲国产中文在线| 91精品国产综合久久久蜜臀图片 | 国产精品一二三区| 亚洲一区二区中文| 91 中文字幕| 久久99国产精品麻豆| 国产精品一区二区三区免费视频| 伊人久久久久久久久久久久 | 国产精品久久久久久搜索| 日韩不卡在线播放| 亚洲欧美日韩一区在线观看| 91高清视频免费观看| 国产成人在线观看网站| 一本色道久久综合| 26uuu久久噜噜噜噜| 秋霞精品一区二区三区| 丝袜美腿亚洲一区| 国产精品久久久久久亚洲调教| 337p粉嫩色噜噜噜大肥臀| 日韩精品五月天| 日本中文字幕成人| 中文字幕+乱码+中文乱码91| 麻豆精品久久久| 成人黄色午夜影院| www日本视频| 成人国产电影网| 含羞草久久爱69一区| 丝袜视频国产在线播放| 国产色91在线| 在线看视频不卡| 日本一级理论片在线大全| 午夜电影久久久| 成人在线看视频| 亚洲男人在线| 亚洲精品成人网| 国产成人免费观看网站| 久久精品一区二区不卡| 欧美激情xxxx性bbbb| 日本视频免费观看| 狠狠色狠狠色综合| 精品国产免费一区二区三区 | 久久久人成影片一区二区三区| 精品成人免费视频| 美女视频免费一区| 成人av资源| 国产天堂在线| 一区二区激情小说| 国产精品69页| av日韩在线播放| 中文字幕日韩综合av| 国产女人被狂躁到高潮小说| 美女日韩在线中文字幕| 91精品国产99久久久久久红楼| 日本福利午夜视频在线| 中文字幕一区二区三区乱码在线| av免费观看大全| 丰满少妇一区| 国产视频精品免费播放| 亚洲xxxx3d动漫| 久久精品二区三区| 波多野结衣精品久久| 国产二区在线播放| 亚洲6080在线| 欧美xxxxxbbbbb| 亚洲综合图色| 久久久久久久久久久国产| 一级黄色片在线看| 91丝袜美腿高跟国产极品老师| 亚洲AV无码成人精品一区| 伊人久久国产| 亚洲精品在线免费观看视频| 99热99这里只有精品| 亚洲一卡久久| 国产精品yjizz| 国产色在线观看| 欧美特级限制片免费在线观看| 国产黑丝一区二区| 国内精品久久久久久久97牛牛 | 欧美精品久久久久久久免费观看| 亚洲一区二区激情| 国产视频一区二区三区在线观看| 成熟丰满熟妇高潮xxxxx视频| 国产精品亚洲欧美日韩一区在线 | 欧美一区二区三区成人| 久久久久亚洲AV成人无在| 国产精品日韩欧美一区| 粉嫩高清一区二区三区精品视频| 黄色片网站在线| 欧美日韩成人综合天天影院| 欧美多人猛交狂配| 国产情侣久久| 精品免费日产一区一区三区免费| 2024最新电影免费在线观看| 欧美卡1卡2卡| 波兰性xxxxx极品hd| 捆绑调教一区二区三区| 奇米视频888战线精品播放| 乱馆动漫1~6集在线观看| 亚洲精品一区二区三区影院 | 国产精品日韩精品欧美精品| 国内精品一区二区| 黄色在线网站噜噜噜| 日韩av影视在线| 毛片视频网站在线观看| 久久看人人爽人人| 亚洲精品中文字幕无码蜜桃| 精品久久久久久久| 国产精品网址在线| 国产传媒在线播放| 欧美成人a∨高清免费观看| 国产亚洲成人精品| caoporen国产精品视频| 看av免费毛片手机播放| 免费毛片在线不卡| 欧美制服第一页| 精华区一区二区三区| 欧美中文字幕亚洲一区二区va在线| 日韩黄色中文字幕| 国产一区二区三区高清播放| 伊人再见免费在线观看高清版| 精品视频成人| 国产69精品久久久久99| 日韩有码电影| 久久成人免费网| 一个色综合网| 欧美激情中文网| 天堂av中文字幕| 狠狠躁夜夜躁人人躁婷婷91| 国产精品无码午夜福利| 狂野欧美一区| 一区二区冒白浆视频| 日韩精品中文字幕一区二区| 国模极品一区二区三区| 噜噜噜在线观看播放视频| 欧美日韩国产首页在线观看| 免费一级肉体全黄毛片| 99久久精品免费看国产 | 噜噜噜躁狠狠躁狠狠精品视频| 日本日本精品二区免费| 伊人亚洲精品| 97成人在线视频| 日本中文字幕在线播放| 亚洲成人激情视频| 亚洲中文无码av在线| 亚洲老司机在线| 国产精品手机在线观看| 男人操女人的视频在线观看欧美| 国产精品视频一二三四区| 亚洲涩涩av| 亚洲iv一区二区三区| 最新日韩精品| 色综合天天狠天天透天天伊人| 青青草免费观看免费视频在线| 欧美高清精品3d| 国产性生活视频| 亚洲午夜久久久久久久久电影网| 少妇av片在线观看| 成人看片黄a免费看在线| 日韩肉感妇bbwbbwbbw| 狠狠色综合网| 亚洲欧美一区二区原创| 欧美电影在线观看完整版| 国产综合香蕉五月婷在线| 涩涩视频在线| 久久久久久美女| 黄色动漫在线观看| 亚洲无亚洲人成网站77777| 折磨小男生性器羞耻的故事| 91久久久久久久久久久久| 最新国产成人在线观看| www.狠狠爱| 成人av手机在线观看| 免费网站在线观看黄| 日韩av一区二区在线影视| 人人干视频在线| 国产精品a久久久久| 伊人久久大香线蕉午夜av| 狠狠操综合网| 免费成人深夜夜行视频| 精品av导航| av一区二区在线看| 国产精品美女久久久久人| 91精品国产综合久久男男 | 欧美暴力喷水在线| 中文字幕一区综合| 日韩欧美视频专区| 婷婷精品国产一区二区三区日韩| 日韩精品丝袜美腿| 狠狠久久综合婷婷不卡| 成人av婷婷| 国产精品免费视频一区二区| 一区二区三区欧洲区| 99国产盗摄| 国产亚洲久久| 亚洲aaaaaa| 日韩激情综合| 国产精品久久久久久久久久直播| 日韩精品三级| 国产精品播放| 理论片一区二区在线| 精品久久久三级| 露出调教综合另类| 精品1区2区| 亚洲v天堂v手机在线| 久久亚洲一区二区| 欧美美乳视频| 伊人久久大香线蕉精品| 久久精品亚洲欧美日韩精品中文字幕| 永久久久久久| 欧美精品不卡| 久久久久久久久久网| 久久xxxx精品视频| 久久久久国产精品熟女影院| 日韩av午夜在线观看| 色综合色综合色综合色综合| 精品一区二区三区久久| 欧洲成人午夜精品无码区久久| 成人高清视频在线| 男人天堂av电影| 国产精品久久久久久久久久久免费看| 婷婷丁香综合网| 洋洋成人永久网站入口| 欧美亚韩一区二区三区| 日本大香伊一区二区三区| 曰批又黄又爽免费视频| 日韩欧美国产系列| 无码精品人妻一区二区三区影院 | 黄色免费在线观看网站| 欧美—级a级欧美特级ar全黄| 黄色在线观看www| 国产精品视频1区| 日韩一区二区三区高清在线观看| 国产一区二区三区高清| 日韩精品午夜| 国产精品成人久久电影| 日本美女一区二区三区视频| 亚洲成人手机在线观看| 99免费精品在线| 亚洲女人久久久| 午夜精品一区二区三区电影天堂 | 丁香花在线电影小说观看| 日韩美女免费线视频| 精品入口麻豆88视频| 就去色蜜桃综合| 亚洲一区二区| 妞干网在线免费视频| 懂色av一区二区夜夜嗨| 国产免费无遮挡吸奶头视频| 一区二区高清视频在线观看| 国产免费一级视频| 日韩欧美国产三级电影视频| 高清毛片在线看| 97人洗澡人人免费公开视频碰碰碰| 成人va天堂| 精品国产一区二区三| 婷婷亚洲五月| www日韩视频| 成人午夜激情影院| 欧美一级特黄高清视频| 欧美性xxxxx极品| 欧美视频久久久| xxxxx成人.com| 日本电影欧美片| 国产99在线播放| 999精品色在线播放| av免费在线播放网站| 波多野结衣中文字幕一区| 在线观看美女av| 欧美亚洲丝袜传媒另类| 亚洲人在线观看视频| 欧美激情xxxx性bbbb| 国产精品va视频| 宅男av一区二区三区| 日本午夜一区二区| 国产特黄级aaaaa片免| 亚洲观看高清完整版在线观看| 国产三级视频在线播放| 色婷婷综合久久久久中文字幕1| 神马电影网我不卡| 久久婷婷开心| 一本色道久久综合亚洲精品高清 | 国产欧美三级电影| 成人在线观看毛片| 国产麻豆9l精品三级站| 日本不卡一二区| 欧美日韩国产综合久久 | 久久久久高潮毛片免费全部播放| 懂色av粉嫩av蜜臀av| 蜜臀av一区二区| 国产一区二区三区视频播放| 在线观看91视频| 丁香婷婷在线观看| 国产精品久久久久久久久久久久久久| 中文在线免费一区三区| 青青青在线观看视频| 国产盗摄视频一区二区三区| 青青草手机在线观看| 日韩免费一区二区三区在线播放| 成人在线网址| 99久久综合狠狠综合久久止| 欧美高清不卡| 国产白袜脚足j棉袜在线观看| 亚洲成av人片www| 手机在线观看毛片| 91av视频在线观看| 91亚洲精品久久久久久久久久久久| 91tv官网精品成人亚洲| 少妇愉情理伦片bd| 亚洲一区二区三区不卡国产欧美| 亚洲精品一区二区三区新线路| 97国产在线视频| 免费电影一区二区三区| 天堂网在线免费观看| 亚洲品质自拍视频网站| 黄色小视频免费在线观看| 97视频免费在线观看| 国产影视精品一区二区三区| av无码精品一区二区三区| 国产精品久久久99| wwwav网站| 日本三级久久久| 久久亚洲影视| 少妇伦子伦精品无吗| 欧美日韩一区二区三区| 国产精品久久一区二区三区不卡| 国产日韩欧美另类| 狠狠久久婷婷| 男人天堂av电影| 777色狠狠一区二区三区| а√天堂8资源中文在线| 日本a级片久久久| 国产毛片精品一区| 亚洲欧美综合自拍| 日韩在线观看免费av| 菁菁伊人国产精品| 国产九九在线观看| 亚洲国产精品影院| 岛国最新视频免费在线观看| 亚洲自拍偷拍视频| 美女精品一区| 久久久久久国产精品视频| 亚洲天堂第二页| 亚洲国产高清在线观看| 成人综合视频在线| 亚洲日本在线看| 精品av中文字幕在线毛片 | 国产高清第一页| 国产精品久久久久久久久果冻传媒| 免费观看国产精品视频| 久久精品视频在线免费观看| 精品人妻无码一区二区色欲产成人 | 欧美区一区二区三区| ****av在线网毛片|