国产秋霞理论久久久电影-婷婷色九月综合激情丁香-欧美在线观看乱妇视频-精品国avA久久久久久久-国产乱码精品一区二区三区亚洲人-欧美熟妇一区二区三区蜜桃视频

Linux fd 系列 — socket fd 是什么?

共 15473字,需瀏覽 31分鐘

 ·

2021-08-20 18:35

堅持思考,就會很酷




socket fd 長什么樣子?


什么是 socket fd ?粗糙的來講,就是網(wǎng)絡 fd,比如我們最常見的 C/S 客戶端服務端的編程模式,就是網(wǎng)絡通信的一種方式。撇開底層和協(xié)議細節(jié),網(wǎng)絡通信文件讀寫從接口上有本質(zhì)區(qū)別嗎?

其實沒啥區(qū)別,不就是讀過來和寫過去嘛,簡稱 IO 。

我們先看一下 socket fd 是什么樣子的?隨便找了個進程

root@ubuntu:~# ll /proc/1583/fd
total 0
lrwx------ 1 root root 64 Jul 19 12:37 7 -> socket:[18892]
lrwx------ 1 root root 64 Jul 19 12:37 8 -> socket:[18893]

這里我們看到 fd 7、8 都是一個 socket fd,名字:socket:[18892]

整數(shù)句柄后面一般會跟一些信息,用于幫助我們了解這個 fd 是什么。舉個例子,如果是文件 fd,那么箭頭后面一般是路徑名稱。現(xiàn)在拆解一下這個名字:

  • socket :標識這是一個 socket 類型的 fd
  • [18892]  :這個是一個 inode 號,能夠唯一標識本機的一條網(wǎng)絡連接;

思考下,這個 inode 號,還能再哪里能看到呢?

在 proc 的 net 目錄下,因為我這個是一個走 tcp 的服務端,所以我們看一下  /proc/net/tcp 文件。這個文件里面能看到所有的 tcp 連接的信息。

root@ubuntu:~# grep -i "18892" /proc/net/tcp
  18: 00000000:1F93 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 18892 1 ffff880197fba580 100 0 0 10 0                     
root@ubuntu:~# grep -i "18893" /proc/net/tcp
  28: 00000000:1F7C 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 18893 1 ffff880197fbad00 100 0 0 10 0    

知識點又來了,/proc/net/tcp 這個文件記錄了 tcp 連接的信息,這份信息是非常有用的。包含了 TCP 連接的地址(16進制顯示),inode 的信息,連接的狀態(tài)等等。


socket fd 是什么?


環(huán)境聲明

Linux 內(nèi)核版本 4.19 

為了方便,如果沒特意說明協(xié)議,默認 TCP 協(xié)議;

socket 可能你還沒反應過來,中文名:套接字 是不是更熟悉點。Linux 網(wǎng)絡編程甚至可以叫做套接字編程。

有些概念你必須捋一捋 。我們思考幾個小問題:

socket 跟 tcp/ip 有什么區(qū)別?

就不該把這兩個東西放在一起比較討論,就不是一個東西。tcp/ip 是網(wǎng)絡協(xié)議棧,socket 是操作系統(tǒng)為了方便網(wǎng)絡編程而設計出來的編程接口而已。

理論基礎是各種網(wǎng)絡協(xié)議,協(xié)議棧呀,啥的。但是如果你要進行網(wǎng)絡編程,落到實處,對程序猿來講就是 socket 編程。

對于網(wǎng)絡的操作,由 socket 體現(xiàn)為 open -> read/write ->close 這樣的編程模式,這個統(tǒng)一到文件的一種形式。

socket 的 open 就是 socket(int domain, int type, int protocol) ,和文件一樣,都是獲取一個句柄。


網(wǎng)絡抽象層次


網(wǎng)絡模型一般會對應到兩種:

  • 完美理論的 OSI 七層模型
  • 現(xiàn)實應用的 5 層模型;

對應關系如下圖(取自 Unix 套接字編程)



不同層次做不同的事情,不斷的封裝,不斷的站在巨人的肩膀上,你將能做的更多。



今天,奇伢剖析的只聚焦在套接字這一層,這是程序猿摸得到的一層,位于所有網(wǎng)絡協(xié)議之上的一層封裝,網(wǎng)絡編程又叫套接字編程,這并不是空穴來風。

套接字,是內(nèi)核對賊復雜的網(wǎng)絡協(xié)議棧的 API 封裝,使得程序猿能夠用極簡的姿勢進行網(wǎng)絡編程。比如寫一個基于 Tcp 的 C/S 的網(wǎng)絡程序,需要用到啥?我們大概暢想下:

  1. 客戶端和服務端都用 socket 調(diào)用創(chuàng)建套接字;
  2. 服務端用 bind 綁定監(jiān)聽地址,用 listen 把套接字轉(zhuǎn)化為監(jiān)聽套接字,用 accept 撈取一個客戶端來的連接;
  3. 客戶端用 connect 進行建連,用 write/read 進行網(wǎng)絡 IO;

程序猿用著好簡單!因為內(nèi)核把事扛了。


socket fd 的類型


上面我們提到了套接字,這是我們網(wǎng)絡編程的主體,套接字由 socket() 系統(tǒng)調(diào)用創(chuàng)建,但你可知套接字其實可分為兩種類型,監(jiān)聽套接字和普通套接字。而監(jiān)聽套接字是由 listen() 把 socket fd 轉(zhuǎn)化而成。


 1   監(jiān)聽套接字


對于監(jiān)聽套接字,不走數(shù)據(jù)流,只管理連接的建立。accept 將從全連接隊列獲取一個創(chuàng)建好的 socket( 3 次握手完成),對于監(jiān)聽套接字的可讀事件就是全連接隊列非空。對于監(jiān)聽套接字,我們只在乎可讀事件。


 2   普通套接字


普通套接字就是走數(shù)據(jù)流的,也就是網(wǎng)絡 IO,針對普通套接字我們關注可讀可寫事件。在說 socket 的可讀可寫事件之前,我們先捋順套接字的讀寫大概是什么樣子吧。

套接字層是內(nèi)核提供給程序員用來網(wǎng)絡編程的,程序猿讀寫都是針對套接字而言,那么 write( socketfd, /* 參數(shù) */)read( socketfd, /* 參數(shù) */) 都會發(fā)生什么呢?

  • write 數(shù)據(jù)到 socketfd,大部分情況下,數(shù)據(jù)寫到 socket 的內(nèi)存 buffer,就結(jié)束了,并沒有發(fā)送到對端網(wǎng)絡(異步發(fā)送);
  • read socketfd 的數(shù)據(jù),也只是從 socket 的 內(nèi)存 buffer 里讀數(shù)據(jù)而已,而不是從網(wǎng)卡讀(雖然數(shù)據(jù)是從網(wǎng)卡一層層遞上來的);

也就是說,程序猿而言,是跟 socket 打交道,內(nèi)核屏蔽了底層的細節(jié)。

那說回來 socket 的可讀可寫事件就很容易理解了。

  • socketfd 可讀:其實就是 socket buffer 內(nèi)有數(shù)據(jù)(超過閾值 SO_RCLOWAT );
  • socketfd 可寫:就是 socket buffer 還有空間讓你寫(閾值 SO_SNDLOWAT );


sockfs 文件系統(tǒng)


socket fd 為什么能具備“文件”的語義,從而和 eventfd,ext2 fd 這樣的句柄一樣,統(tǒng)一提供對外 io 的樣子?

核心就是:sockfs ,這也是個文件系統(tǒng),只不過普通用戶看不見,這是只由內(nèi)核管理的文件系統(tǒng),位于 vfs 之下,為了封裝 socket 對上的文件語義。

// net/socket.c
static int __init sock_init(void)
{
    // 注冊 sockfs 文件系統(tǒng)
    err = register_filesystem(&sock_fs_type);
    // 內(nèi)核掛載
    sock_mnt = kern_mount(&sock_fs_type);
}

其中最關鍵的是 sock_mnt 這個全局變量里面的超級塊的操作表 sockfs_ops

// net/socket.c
static const struct super_operations sockfs_ops = {
    .alloc_inode    = sock_alloc_inode,
    .destroy_inode  = sock_destroy_inode,
    .statfs     = simple_statfs,
};

這個是每個文件系統(tǒng)的核心函數(shù)表,如上指明了 inode 的分配規(guī)則(這里又將體現(xiàn)依次結(jié)構(gòu)體內(nèi)嵌組合+類型強轉(zhuǎn)的應用)。

讀者朋友還記得 inode 和 ext4_inode_info 的關系嗎?在 Linux fd 究竟是什么?一文中有提到這個:

inode 是 vfs 抽象的適配所有文件系統(tǒng)的結(jié)構(gòu)體,但分配其實是有下層具體文件系統(tǒng)分配出來的,以 ext4 文件系統(tǒng)來說,使用 ext4_alloc_inode 函數(shù)分配出 ext4_inode_info 這個大結(jié)構(gòu)體,然后返回的是 inode 的地址而已。

劃重點:struct inode 內(nèi)嵌于具體文件系統(tǒng)的 “inode” 里,vfs 層使用的是 inode,ext4 層使用的是 ext4_inode_info ,不同層次通過地址的強制轉(zhuǎn)化類型來切換結(jié)構(gòu)體。

那么類似,sockfs 也是如此,sockfs 作為文件系統(tǒng),也有自己特色的 “inode”,這個類型就是 struct socket_alloc ,如下:

struct socket_alloc {
    struct socket socket;
    struct inode vfs_inode;
};

這個結(jié)構(gòu)體關聯(lián) socket 和 inode 兩個角色,是“文件”抽象的核心之一。分配 struct socket 結(jié)構(gòu)體其實是分配了 struct socket_alloc 結(jié)構(gòu)體,然后返回了 socket_alloc->socket  字段的地址而已。

劃重點:vfs 層用的時候給 inode 字段的地址,socket 層的時候給 socket 字段的地址。不同抽象層面對于同一個內(nèi)存塊的理解不同,強制轉(zhuǎn)化類型,然后各自使用

從文件的角度來看 socket,模塊如下:




回調(diào)喚醒的通用做法?


先鋪墊一個小知識點:內(nèi)核里面有回調(diào)喚醒的實現(xiàn),里面有用到一種 wait queue 的做法,其實很簡單的原理。

大白話原理:你要走可以,把聯(lián)系方式留下,我搞好之后通知你(調(diào)用你留下的函數(shù),傳入你留下的參數(shù))。



拿 socket 來說,struct sock 里面就有個字段 sk_wq ,這是個表頭,就是用來掛接等待對象的。

誰會掛?

就以 epoll 池來說,epoll_ctl 注冊 socket fd 的時候,就會掛一個 wait 對象到 sk->sk_wq 里?;卣{(diào)參數(shù)為 ep_poll_callback ,參數(shù)為 epitem 。

這樣 epoll 給 socket 留下聯(lián)系方式了( wait 對象 ),socket 有啥事就可以隨時通知到 epoll 池了。

能有什么事?

socket 可讀可寫了唄。sk buffer 里面有數(shù)據(jù)可以讀,或者有空間可以寫了唄。對于監(jiān)聽類型的 socket,有新的連接了唄。epoll 監(jiān)聽的不就是這個嘛。


socket 編程 ?


服務端:

  1. socket( ) 創(chuàng)建出 socketfd;
  2. bind( )  綁定一個端口(和客戶端約定好的知名端口號);
  3. listen( ) 講套接字轉(zhuǎn)化成監(jiān)聽套接字;
  4. accept( ) 等待客戶端的建連請求;
  5. 建連之后 read/write 處理數(shù)據(jù)即可(一般和監(jiān)聽線程并發(fā));

客戶端:

  1. socket( ) 創(chuàng)建出 socketfd;
  2. connect( ) 向指定機器、端口發(fā)起建連請求;
  3. 建連之后,read/write 處理數(shù)據(jù);


下面就幾個關鍵函數(shù)做個簡要實現(xiàn)。


 1   socket 函數(shù)


定義原型:

#include<sys/socket.h>
int socket(int family, int type, int protocol)

簡要跟蹤下內(nèi)部實現(xiàn)

socket 系統(tǒng)調(diào)用對應了 __sys_socket 這個函數(shù)。這個函數(shù)主要做兩件事情:

  1. 第一件事:調(diào)用 socket_create 函數(shù)創(chuàng)建好 socket 相關的結(jié)構(gòu)體,主要是 struct socket ,還有與之關聯(lián)的 socket sock 結(jié)構(gòu),再往下就是具體網(wǎng)絡協(xié)議對應的結(jié)構(gòu)體(旁白:這里實現(xiàn)細節(jié)過于復雜,不在文章主干,故略去 10 萬字);
  2. 第二件事:調(diào)用 sock_map_fd 函數(shù)創(chuàng)建好 struct file 這個結(jié)構(gòu)體,并與第一步創(chuàng)建出的 struct socket 關聯(lián)起來;

涉及的一些函數(shù)調(diào)用

__sys_socket
    // 創(chuàng)建 struct socket 結(jié)構(gòu)體
    -> sock_create
            // 創(chuàng)建 struct socket 結(jié)構(gòu),并且關聯(lián)特殊 inode
            -> sock_alloc
            // pf 是根據(jù) family 從 net_families 這個全局表中取出的操作函數(shù)表,用來創(chuàng)建具體網(wǎng)絡協(xié)議結(jié)構(gòu)的;  
            // 比如 IPv4 對應的 family 就是 AF_INET ,對應的函數(shù)是 inet_create
            // 在這里面會賦值 sock->ops 為對應協(xié)議族的操作函數(shù)表(比如 inet_stream_ops)
            -> pf->create
                    // struct sock 結(jié)構(gòu)體的創(chuàng)建(sk->sk_prot 的賦值就在這里,比如 tcp_prot )
                    -> sk_alloc
                    // struct sock 結(jié)構(gòu)體的初始化(比如 sk_receive_queue, sk_write_queue, sk_error_queue 就是在這里初始化的)
                    // 可讀寫的關鍵函數(shù) sock_def_readable,sock_def_write_space 也是在這里賦值的
                    -> sock_init_data
    // 創(chuàng)建 struct file 結(jié)構(gòu)體,并且關聯(lián) struct socket
    -> sock_map_fd

先說 socket 函數(shù):

  1. socket( ) 函數(shù)只負責創(chuàng)建出適配具體網(wǎng)絡協(xié)議的資源(內(nèi)存、結(jié)構(gòu)體、隊列等),并沒有和具體地址綁定;
  2. socket( ) 返回的是非負整數(shù)的 fd,與 struct file 對應,而 struct file 則與具體的 struct socket 關聯(lián),從而實現(xiàn)一切皆文件的封裝的一部分(另一部分 inode 的創(chuàng)建處理在 sock_alloc 的函數(shù)里體現(xiàn));

再簡要說下內(nèi)部細節(jié):

sock_create 函數(shù)里,會根據(jù)協(xié)議族查找對應的操作表,以 AF_INET 協(xié)議族舉例,pf->createinet_create ,主要做兩件事:

  1. sock->ops 按照協(xié)議類型賦值成具體的函數(shù)操作表,比如 tcp 的就是 inet_stream_ops ;
  2. 創(chuàng)建了 struct sock 對象,并且把 struct sock 初始化,并和 struct socket 進行關聯(lián);

著重提一點,sock_init_data  函數(shù)( net/core/sock.c )主要是初始化 struct sock 結(jié)構(gòu)體的,提兩點最關鍵的:

第一點:接收隊列和發(fā)送隊列在這里初始化;

  • sk_receive_queue:套接字接收到的數(shù)據(jù)(sk_buff 里面是純粹的用戶數(shù)據(jù)哦,沒有 header 啥信息);
  • sk_write_queue:套接字要發(fā)送的數(shù)據(jù);
  • sk_error_queue:掛接一些 pengding 的 error 信息;

第二點:socket 的喚醒回調(diào)在這個地方設置;

   sk->sk_data_ready   =   sock_def_readable;
   sk->sk_write_space  =   sock_def_write_space;

為什么這里很重要,因為這個跟 socket fd 可讀可寫的判斷邏輯,數(shù)據(jù)到了之后的喚醒路徑息息相關。簡述下回調(diào)鏈路(以套接字層為主干,其他的流程簡略描述):

sk->sk_data_ready(數(shù)據(jù)到了,該通知留下過聯(lián)系方式的人了)
tcp_v4_rcv(具體協(xié)議棧處理函數(shù))
軟中斷
硬中斷

再說下結(jié)構(gòu)體:

繼續(xù)說 struct sock ,這個對象有意思了,這個也是以組合的方式往下兼容的,同一個地址強轉(zhuǎn)類型得到不同層面的結(jié)構(gòu)體。原理就在于:他們是一塊連續(xù)的內(nèi)存空間,起始地址相同。

sock -> inet_sock -> inet_connection_sock-> tcp_sock

示意圖:



小思考:struct socketstruct sock 是兩個不同的結(jié)構(gòu)體?

是的。這兩個是不同的結(jié)構(gòu)體。屬于套接字層的兩個維度的描述,一個面向上層,一個面向下層。

struct socket 在內(nèi)核的注釋為:

struct socket - general BSD socket

struct sock 在內(nèi)核的注釋為:

struct sock_common - minimal network layer representation of sockets

struct socket 是內(nèi)核抽象出的一個通用結(jié)構(gòu)體,主要作用是放置了一些跟 fs 相關的字段,而真正跟網(wǎng)絡通信相關的字段結(jié)構(gòu)體是 struct sock 。它們內(nèi)部有相互的指針,可以獲取到對方的地址。

struct socket 這個字段出生的時候其實就和一個 inode 結(jié)構(gòu)體伴生出來的,由 socketfs  的 sock_alloc_inode  函數(shù)分配。

struct sock 這個結(jié)構(gòu)體是 socket 套階字核心的結(jié)構(gòu)(注意,還有個結(jié)構(gòu)是 struct socket,這兩個是不同的結(jié)構(gòu)體哦)。這個是對底下具體協(xié)議做的一層抽象封裝,比如在分配 struct sock 的時候,如果是 tcp 協(xié)議,那么 sk->sk_prot 會賦值為 tcp_prot ,udp 協(xié)議賦值的是 udp_prot ,之后的一系列協(xié)議解析和處理就是調(diào)用到對應協(xié)議的回調(diào)函數(shù)。

小思考:socket fd 可以和文件一樣用 write(fd, /*xxxx*/ ) 這行的調(diào)用,為什么?

write(fd, /*xxxx*/) 進到內(nèi)核首先是到 vfs 層,也就是調(diào)用到 vfs_write ,在這個里面首先獲取到 file 這個結(jié)構(gòu)體,然后調(diào)用下層注冊的回調(diào),比如 file->f_op->write_iterfile->f_op->write ,所以,關鍵在 file->f_op 這個字段,對吧?

現(xiàn)在的問題是,這個字段是啥呢?

這個字段在 file 結(jié)構(gòu)體生成的時候,根據(jù)你的“文件”類型賦值的,這個在之前文件系統(tǒng)章節(jié)提過這個,比如 ext2 的文件,那么就是 ext2_file_operations ,socketfd 是 socket_file_ops

vfs_write    =>  
                -> socket_file_ops (sockfs)
                -> ext2_file_operations (ext2)
                -> ext4_file_operations (ext4)
                -> eventfd_fops 

可以看下 socket_file_ops  的定義:

static const struct file_operations socket_file_ops = {
    .llseek =   no_llseek,
    .read_iter =    sock_read_iter,
    .write_iter =   sock_write_iter,
    .poll =     sock_poll,
    // ...
}    

所以,vfs_write 調(diào)用到的將是 sock_write_iter,而這個里面就是調(diào)用到 sock_sendmsg ,從而走到網(wǎng)絡相關的處理流程。

// sock_sendmsg 實際調(diào)用;
static inline int sock_sendmsg_nosec(struct socket *sock, struct msghdr *msg)
{
    int ret = sock->ops->sendmsg(sock, msg, msg_data_left(msg));
    return ret;
}

還記得上面在 socket 初始化的時候 socket->opssock->sk_prot 兩個回調(diào)函數(shù)操作表的賦值嗎( tcp ):

  • socket->ops => inet_stream_ops
  • sock->sk_prot => tcp_prot

這樣從 vfs 進來,轉(zhuǎn)接到具體的協(xié)議處理模塊去了。


 2   bind 函數(shù)


對應內(nèi)核 __sys_bind 函數(shù),做的事情很簡單:

  1. 先通過 fd 找到對應的 struct socket 結(jié)構(gòu)體;
  2. 然后把 address 和 socket 綁定對應起來(調(diào)用 sock->ops->bind 函數(shù));

tcp 連接的對應的 bind 函數(shù)是 inet_bind,里面做的事情很簡單,就是簡單的查一下端口有沒有被占用,沒有被占用的話端口就賦值給 inet_sock->inet_sport 這個字段。

inet_sock 則是由 sk 強轉(zhuǎn)類型得到。

思考個小問題:在上面的圖中,bind 這個函數(shù)只在服務端用到?

為啥客戶端沒用這個函數(shù)呢?

其實,客戶端也是可以用 bind 這個函數(shù),但是沒必要

理解下 bind 函數(shù)的作用:給這個 socketfd 綁定地址(IP:Port)用的??蛻舳瞬恍枰且驗椋喝绻麤]設置,內(nèi)核在建連的時候會自動選一個臨時的端口號作為本次 TCP 連接的地址。一般客戶端也不在意端口號,只要能和服務端正常通信就好,所以客戶端一般沒有 bind 調(diào)用。

服務端必須要用這個是因為服務端必須提前明確指定監(jiān)聽的 IP 和 Port (不然誰知道向哪里發(fā)起連接呢)。


 3   listen 函數(shù)


其實 socket( ) 創(chuàng)建出來的套接字并無客戶端和服務端之分,是 listen 函數(shù)讓 socket 有了不一樣的屬性,成為監(jiān)聽套接字。

listen 系統(tǒng)調(diào)用主要做兩件事:

  1. 通過 fd 找到 struct socket 結(jié)構(gòu)體;
  2. 調(diào)用 sock->ops->listen 函數(shù)(對應 inet_listen );

inet_listen  做啥了?內(nèi)核注釋:

Move a socket into listening state.

簡單看下 inet_listen 的實現(xiàn)功能:

  1. 檢查 socket 狀態(tài),類型,必須為流式套接字才能轉(zhuǎn)化成監(jiān)聽套接字;
  2. 調(diào)用 inet_csk_listen_start ;

inet_csk_listen_start 做啥了?

  1. 初始化請求隊列 icsk->icsk_accept_queue ;
  2. 套接字狀態(tài)設置成 TCP_LISTEN
  3. 獲取到之前 bind 的端口,如果沒有設置,那么就會用個臨時的端口;
  4. 把監(jiān)聽套接字加入到全局 hash 表中;

劃重點:套接字的轉(zhuǎn)變就在于此。


 4   accept 函數(shù)


inet_accept ( net/ipv4/af_inet.c )注釋:

Accept a pending connection. The TCP layer now gives BSD semantics.

這個主要是從隊列 icsk->icsk_accept_queue 中取請求,如果隊列為空,就看 socket 是否設置了非阻塞標識,非阻塞的就直接報錯 EAGAIN,否則阻塞線程等待。

所以,監(jiān)聽套接字的可讀事件是啥?

icsk_accept_queue 隊列非空。

這個隊列什么時候被填充的?

tcp_child_process
    -> tcp_rcv_state_process

這個也是底層網(wǎng)絡協(xié)議回調(diào)往上調(diào)用的,tcp 三次握手之后,建立好的連接就在一個隊列中 accept_queue ,隊列非空則為只讀。由 tcp 的協(xié)議棧往上調(diào)用,對應到 socket 層,還是會調(diào)用到 sk->sk_data_ready 。

這里還是以 epoll 管理監(jiān)聽套接字來舉例。這個跟上面講的數(shù)據(jù)來了一樣,都是把掛接在 socket 本身上的 wait 對象進行喚醒(調(diào)用回調(diào)),這樣就會到 ep_poll_callback ,ep_poll_callback 就會把監(jiān)聽套接字對應的 ep_item 掛到 epoll 的 ready 隊列中,并且喚醒阻塞在 epoll_wait 的線程,從而實現(xiàn)了監(jiān)聽套接字的讀事件的觸發(fā)的流程。


 5   connect 函數(shù)


這個沒啥講的,就是由客戶端向服務端發(fā)起連接的時候調(diào)用,一般也和 epoll 配合不起來,略過。


句柄事件


深入剖析 epoll 篇 我們就提到過,epoll 池可以管理 socket fd ,用于監(jiān)聽 socket fd 的可讀,可寫事件。那么問題來了,socket fd 的可讀可寫事件分別是啥?代表了什么含義?

這個要把服務端的監(jiān)聽類型的 socket fd 和傳輸數(shù)據(jù)的 socket fd 分開來說。

監(jiān)聽類型的 fd:

  1. 有 client 建連,則觸發(fā)可讀事件;
  2. 句柄被 close ,則觸發(fā)可讀事件;

數(shù)據(jù)類型的 fd:

  1. sk buffer 有可讀的數(shù)據(jù),觸發(fā)可讀事件;
  2. sk buffer 有可寫的空間,觸發(fā)可寫事件;
  3. 句柄杯 close,連接關閉的時候,也是可讀的;

還有,如果 socket 之上有 pending 的 error 待處理,那么也會觸發(fā)可讀事件。


epoll 池怎么配合?


最后,我們再回憶一下,epoll 池管理的 socket fd 是怎么及時觸發(fā)喚醒的呢?

換句話說,socket fd 數(shù)據(jù)就緒之后,怎么能及時的喚醒被阻塞在 epoll_wait 的線程?

還記得套接字 buffer 數(shù)據(jù)來了的時候的回調(diào)嗎?

調(diào)用的是 sk->sk_data_ready 這個函數(shù)指針,這個字段在 socket 初始化的時候被賦值為  sock_def_readable ,這個函數(shù)里面會依次調(diào)用所有掛接到 socket 的 wait 隊列的對象( 表頭:sk->sk_wq ),在這個 wait 隊列中存在和 epoll 關聯(lián)的秘密。

回憶下,在  深入剖析 epoll 篇 提到,epoll_ctl 的時候,在把 socket fd 注冊進 epoll 池的時候,會把一個 wait 對象掛接到這個 socket 的 sk->sk_wq 中 ,回調(diào)函數(shù)就是 ep_poll_callback 。

這個wait 對象就是數(shù)據(jù)就緒時候的聯(lián)系方式,這樣把 socket 數(shù)據(jù)就緒的流程和 epoll 關聯(lián)上了。

也就是說,sk->sk_data_ready 會調(diào)用到 ep_poll_callback ,ep_poll_callback 這個函數(shù)處理很簡單,做兩件事情:

  1. 把 socket 對應的 ep_item 掛接到就緒隊列中;
  2. 把阻塞在 epoll_wait 的線程(Linux 進程和線程本質(zhì)無區(qū)別)投遞到就緒隊列中,等待內(nèi)核調(diào)度(也就是所謂的喚醒,實現(xiàn)機制很簡單,就是 epoll_wait 阻塞切走之前,會創(chuàng)建出一個 wait 對象,掛到 epoll 池上,后續(xù)喚醒就能以此為依據(jù));
ep_poll_callback
sk->sk_data_ready
tcp_v4_rcv(具體協(xié)議棧處理函數(shù))
軟中斷
硬中斷

數(shù)據(jù)來了

最后用一張簡要的圖展示結(jié)構(gòu)體之間的關系:


總結(jié)


  1. vfs 下有一個 sockfs 的抽象層,是把 socket 抽象成“文件” fd 的關鍵之一;
  2. socket fd 能夠和文件 IO 一樣,使用 write/read 等系統(tǒng)調(diào)用,就得益于 vfs 幫你做的轉(zhuǎn)接。那 socket() 函數(shù)調(diào)用是不是就和 open 文件 fd 的效果是一樣的呀?是的,都是構(gòu)建并關聯(lián)各種內(nèi)核結(jié)構(gòu)體;
  3. epoll 池能管理 socketfd,因為 socket fd 實現(xiàn) poll 接口;
  4. epoll_ctl 注冊 socket fd 的時候,掛了個 wait 對象在 socket 的 sk_wq 里,所以數(shù)據(jù)就緒的時候,socket 才能通知到 epoll;
  5. epoll_wait 切走的時候掛了個 wait 對象在 epoll 上,所以 epoll 就緒的時候,才能有機會喚醒阻塞的線程;
  6. 套接字由 socket() 創(chuàng)建出來,客戶端和服務端都是,listen() 調(diào)用可以把套接字轉(zhuǎn)化成監(jiān)聽套接字;
  7. 監(jiān)聽套接字一般只監(jiān)聽可讀事件,關注連接的建立,普通套接字走數(shù)據(jù)流,關注數(shù)據(jù)的讀寫事件;


后記


網(wǎng)絡模塊賊復雜,但是套接字編程賊簡單,我們先從套接字編程入手,慢慢掌握吧。先理解 socket fd 是什么,邁出第一步。

~完~


瀏覽 171
點贊
評論
收藏
分享

手機掃一掃分享

分享
舉報
評論
圖片
表情
推薦
點贊
評論
收藏
分享

手機掃一掃分享

分享
舉報

感谢您访问我们的网站,您可能还对以下资源感兴趣:

国产秋霞理论久久久电影-婷婷色九月综合激情丁香-欧美在线观看乱妇视频-精品国avA久久久久久久-国产乱码精品一区二区三区亚洲人-欧美熟妇一区二区三区蜜桃视频 亚洲国产成人久久| 日本成人黄色视频| 亚洲中文字幕观看| 成人免费乱码大片a毛片蜜芽 | 欧美性猛交XXXX乱大交3| 久久久久久久麻豆| 国产精品一区二区在线观看| 日韩中文字幕国产| 精品视频导航| 囯产精品久久久久久久久久久久久久 | 无码国产视频| 国产AV小电影| 操精品| 国产一区二区不卡亚洲涩情| 粉嫩AV在线| 日韩老熟妇| 日本AI高清无码在线观看网址 | 九九这里有精品| 无卡无码| www五月天| 婷婷丁香色五月| 国产精品久免费的黄网站| 超碰在线最新| 中文大香蕉视频| 99成人| 91无码在线观看| 欧美黄色片在线观看| 亚洲精品色图| 欧美搡BBBB搡BBB| 欧美成人中文字幕在线| 夜夜骑天天| 人人摸人人看人人| 日韩在线大香蕉| 欧美精品无码久久久精品酒店| 99视频在线| 日本免费一区二区三区| 欧美成人久久| 国产十八岁在线观看| 亚洲有码在线| 日本无码高清| 乱子伦国产精品视频| 60分钟上大床又黄又爽| 国产精品久久久久无码| 久久足交| 青草无码| 日本精品视频一区二区| 99热精品免费观看| 天天操人人操| 蜜桃久久久亚洲| aⅴ免费观看| 中文字幕高清视频| 成人精品永久免费视频99久久精品| 欧美精品久久久久久久久爆乳| 操逼逼视频| 国产黄色视频在线| 久久国产无码| 欧美黄片在线| 蜜臀色欲AV无码人妻| 成人在线中文字幕| 天天草天天射| 国产精品久久久久久久久久久免费看 | 国产精品国产伦子伦露看| 中国女人操逼视频| 亚洲性爱电影| 亚洲无码高清在线观看| 日本a在线| 亚洲天堂偷拍| 天天射视频| 天天做天天爱| 激情视频网址| 中文字幕视频在线| 国产伦精品一区二区三区妓女| 囯产精品宾馆在线精品酒店| 成年人黄色网址| 先锋影音av在线| 一区二区三区四区久久| 国模精品无码一区二区免费蜜桃| a免费视频| www.第四色| 九九九久久久| 岛国免费av| 中文字幕第98页| 久久99精品久久久久久| 欧美日本亚洲| 中文字字幕在线中文乱码电影| 波多野结衣av无码| 99在线免费观看| 91久久精品日日躁夜夜躁国产| 99热国产精品| 亚洲女人天堂| 国产九九九| 麻豆传媒视频观看| A片观看视频| 中文字幕在线观看a| 日本视频网| 欧美成人精品a| 国产日本在线视频| 偷窥丶亚洲丶熟女| 亚洲中文视频在线| 五月天激情片| 先锋AV资源站| 久草国产在线视频| 成人做爰黄A片免费看| h片在线免费观看视频| 欧美精品一卡二卡| 日日干av| 大香蕉久热| 亚洲精品成人7777777| 日韩综合久久| 国产传媒自拍| 蜜臀久久99精品久久久久久酒店| 日韩无码免费| 久草蜜臀| 婷婷五月天丁香成人社区| 炮友五月天| 天天射中文| 91色图| 亚洲日韩精品无码| 在线视频一区二区三区四区| 国产传媒_色哟哟| 蜜桃视频一区二区三区四区使用方法| 91精品视频网站| www.超碰在线| 91久色| 亚洲无码成人| 成人国产精品免费观看| 午夜福利sw| 噜噜噜AV| 国产精品99精品| 激情久久AV一区AV二区AV三区| 久久女人网| 超碰人人91| 亚洲AV无码成人精品区| 国产激情精品| 免费无码高清| 免费看AV大片| 成人毛片一区二区三区| 国产一区久久| 狠狠狠狠狠操| 国产免费a片| 少妇人妻无码| 无码国产精品一区二区免费96| 综合伊人| 久久久亚洲AV| 国产精品一区一区三区| 99国产综合| 九九热视频在线观看| 久久99久久99久久99| 国产精品av在线| 狠狠操在线| 伊人黄色| 波多野结衣av在线观看窜天猴 | 无码人妻A片一区二区青苹果| 精品无码人妻一区二区| 五月婷婷丁香综合| 亚洲欧美精品| 久久久久国产一区二区三区四区| 美女AV网站| 新超碰97| 国产一级AV片| 水密桃网站| 精产国品一区二区区别| 久久人搡人人玩人妻精AV香蕉| 国产免看一级a一片成人aⅴ| 五月天综合久久| 日本内射在线播放| 欧美日韩一区二区在线观看| 无码一区二区三区在线| 国产小视频在线观看| 亚洲性爱手机版| 性爱福利导航| 中文字幕乱码中文乱码91| 日韩中文字幕高清| 嫩草亚洲小泬久久夂| 操逼国产| 亚洲色成人网站www永久四虎| av不卡在线观看| 97国产精品人人爽人人做| 中文字幕不卡在线| 日韩三级一区二区| 三级99| 无码六区| 北条麻妃黄色视频| 九哥操逼视频| gay成人在线观看| 中文字幕一区三区人妻视频| 日本在线网站| 中文字幕第一| 天天日天天操天天射| 欧美亚洲综合手机在线| 午夜无码久久| 日韩激情一区| 92丨九色丨偷拍老熟女| 18国产免费视频| 特级特黄A级高潮播放| A片黄色| 日韩无码性爱视频| 一级片| 国产在线观看免费成人视频 | 亚洲天天| 一级A片免费黄色视频| 久久久久久无码精品亚洲日韩麻豆| 超碰牛牛| 中文字幕免费在线播放| 大香蕉毛片| 一级成人片在线观看| 超碰综合| av在线观看中文字幕| 黄色三级在线观看| 无套免费视频欧美| 2016超碰| 日韩A√| 日韩黄色三级片| www.色欲av| 一本一道波多野结衣潮喷视频| 中文字幕亚洲欧美| 精品国产99| 国产欧美精品在线观看| 欧美一级免费A片| 精品欧美视频| 九九热在线视频| 特级特黄A级高潮播放| 日韩精品视频免费在线观看| 日韩中文字幕在线观看视频| 国产色情性黄片Av网站| 日韩乱码| 亚洲综合在线观看视频| 成人黄色一级片| 亚洲搞清视频日本| 丁香六月激情婷婷| 小泬BBBBBB免费看| 九九色综合| 黄片视频在线免费播放| 88AV在线视频| jiujiuav| 狠狠操狠狠色| 国产美女AV| 91夫妻视频| 久久久精品影院| 超碰青青青| 久久与婷婷| 国产一区二区不卡| 狼人综合视频| 杨贵妃一级婬片90分钟| 操东北老女人| 日韩免费性爱视频| 97亚洲精品| 成人无码中文字幕| 大香蕉伊人青青草| 亚洲精品伊人| 三级片在线视频| 120分钟婬片免费看| 久久偷拍网| 午夜无码福利| 丁香伊人| 精品蜜桃秘一区二区三区在线播放 | 亚洲草片| 黄片网址大全| 天天射天天爽| 日本草久| 精品一区二区三区四区五区六区| 91AV在线看| 欧美在线观看视频一区| 伊人在线视频观看| 爱爱毛片| 国产91页| 韩国三级av| 午夜免费福利| av无码av天天av天天爽| 嫩BBB槡BBBB槡BBBB撒尿| 另类老妇奶性BBWBBw| 日韩成人AV电影| 男女啪啪| 欧美淫秽视频| 色婷视频| 天天日天天操天天干| 国产精品欧美性爱| 在线a | 亚洲天堂日本| 成人在线网| 91丨精品丨国产丨丝袜| 无码精品久久| www.a日逼| 日韩在线观看网址| 91丨九色丨东北熟女| 欧美在线va| 日韩一级黄色毛片| 久久久久99精品成人片欧美一区| 在线播放91灌醉迷J高跟美女| 青青草国产亚洲精品久久| 亚洲无码久久飞鱼网站| 国产乱伦毛片| 久久免费观看视频| 国产伦精品一区二区三区妓女下载 | 在线国产91| 人妻少妇精品视频| 国产老女人农村HD| 国产成人三级片| 爱爱视频日韩| 日韩av在线电影| www.中文字幕| 免费成人在线看片黄| AV毛片| 欧美精产国品一二三产品动漫| 中文视频免费播放| 日韩在线高清视频| 午夜视频网站| 激情成人五月天| 美女性爱视频网站| 97视频在线免费观看| 青青草东路热vv| 大香蕉做爱视频| 国产精品爽爽久久久久| 2014亚洲天堂| 97精品人妻一区二区三区香蕉| 日韩高清中文字幕| 涩久久久| h片网站在线观看| 国产综合第一页| 久久久无码电影| 蜜臀99久久精品久久久懂爱 | 91小视频在线观看| 国产精品乱草| 欧美日韩中文字幕在线视频| 大香伊人网| 国产成人V在线精品一区| 无码蜜桃吴梦梦| 又紧又嫩又爽无遮挡免费| 亚洲日韩中文无码| 国产乱子伦-区二区三区熟睡91 | 起碰在线视频| 一区二区三区视频在线| 國產美女AV操逼網站| 成人av免费观看| 波多野结衣AV在线播放| 青青草视频免费在线观看| 最近中文字幕免费mv第一季歌词大全 | 日本不卡在线视频| 欧美在线国产| 成人电影无码| 欧美视频操逼| 亚洲欧美成人在线视频| 欧美操B视频| 免费看黄色AV| 亚洲无码高清视频在线观看| 东北骚妇大战黑人视频| 免费操逼网| 国产女主播在线播放| 午夜AV在线观看| 黄色视频在线观看亚洲一区二区三区免费| 波多野结衣大战黑人| 国产在线激情| www.日韩av| 大香蕉一区二区三区| 男人插女人网站| 国精产品一区二区三区黑人和中国| 亚洲videos| 成人无码动漫A片| 亚欧美日韩| 午夜欧美| 亚洲成a人无码| 91干| 影音先锋91视频| 丁香五月色情| 日本親子亂子倫XXXX| 婷婷色综合| 国产午夜成人视频| 一区二区三区无码在线观看| av一卡二卡| 99综合网| 三级在线网| 免费看一区二区三区A片| 性爱免费视频网站| 天天色色| ww无码| a色视频| 日韩A片免费看| 亚洲va欧美va天堂v国产综合 | 欧美在线| 国产日韩欧美| 欧美级毛片一进一出夜本色| 无码日韩av| 女人18片毛片60分钟黃菲菲| 久久露脸国语精品国产91| 日皮视频免费在线观看| 九色丨蝌蚪丨老版熟女| 亚洲激情网站| 大鸡巴久久久久久久| 色玖玖| 日本视频一区二区| 人人操人人摸人人射| 日韩av毛片| 久久久久久久久久久久成人 | 91内射视频| 午夜无码福利视频| 欧美77777| 五月丁香视频在线观看| 欧美黄色激情视频网站| 国产AV在| 日韩精品无码人妻| 伊人网大香蕉| 女生操逼网站| 人人人人人妻| 国产性生活| 极品少妇久久久| 无码任你躁久久久久| 99ri国产| 中文字幕东京热| 五月丁香网站| 亚洲午夜免费视频| 亚洲成人动漫在线| AV无码高清| 欧美在线免费视频| 黄p网站| 亚洲精品视频无码| 69国产成人精品二区| 国产精品揄拍一区二区| 激情五月婷婷五月| 嘿嘿午夜影院| 中文字幕精品无码亚| 在线观看免费国产| 久久99高清| 大香蕉伊人久久| 凹凸熟女凹凸BBWBBW| 国产精品v欧美精品v日韩精品 | 亚洲第一色网| 欧美日韩亚洲天堂| 亚州一级二级| 久久国产免费| 99re免费视频| 国产精品久免费的黄网站| 亚洲乱伦| 人人干人人操人人摸| 成人丁香五月| 国产一级免费观看| 91视频播放| 一区二区三区无码高清| 日韩乱伦网站| 狠狠躁夜夜躁人人爽人妻| 亚洲在线视频免费观看| 亚洲av大全| 波多野结衣高潮| 91无码精品| 欧美日韩国产中文字幕| 国产成人三级视频| 国内综合久久| 尤物av| 国产又大又粗| 国产网站免费| 日本少妇午夜福利| 国产精品A片守望| www.簧片| 亚洲人人18XXX—20HD| 久久亚洲日韩天天做日日做综合亚洲 | 成人毛片在线视频| 91ThePorn国产| 久色视频福利| 午夜成人av| 久操视频在线观看免费| 99精品自拍| 欧美一级特黄AAAAAA片在线视频 | 51成人网| 天堂中文资源库| 91久久婷婷亚洲精品成人| 免费aa片| 欧美视频一区二区三区| 日本黄色中文字幕| 久久久8| 99久热在线精品| 国产无码内射视频| 精品人妻一区二区三区四区不卡在 | 国产欧美日韩| 91人妻精| 嫩BBB揍BBB揍BBB| 亚洲超碰在线观看| 91久久久久久久久久| 精产国品一区二区| 成人视频网站在线观看| 91麻豆精品传媒国产| 操逼啦| AV在线免费网站| 香蕉在线观看| 国产福利美女网站| 色卻A| 亚洲性爱电影| 久久99热这里只频精品6学生| 偷拍777| 精品一区二区三区免费| 国产精品九九九九九九| 欧美精品操逼| 18SAV| 色情欧美一级A片| 人人妻人人澡人人爽人人| 中文在线字幕免费观看电视剧大全| 久久久蜜桃| 3D动漫精品啪啪一区二区竹笋 | 日韩欧美片| 国产精品怡红院有限公司| 在线观看亚洲视频| 欧美综合国产| 欧美色图另类| 欧美精品成人免码在线| 国产精品乱子伦一区二区三区视频| 抽插影院| 日韩美在线| 制服丝袜一区| 亚洲91无码精品一区在线播放| 亚洲AV无码一区毛片AV| 伊人成人视频在线观看| 国产又爽又黄免费视频免费观看| 免费在线观看黄色视频| 水果派解说在线观看| 韩日一区| 国产精品人妻AⅤ在线看| 一级一级一级做a免费一级做a | 欧美性成人| 成人精品一区二区三区电影| 日韩1234区| 国产又粗又长又硬又大毛苴茸图片 | 99re视频在线观看| 神马午夜福利视频| 亚洲激情网站| 一级片在线观看视频| jizz在线免费观看| 性无码一区二区三区| 91丨熟女丨首页| 国产一区二区三区无码| 91欧美日韩综合| 777Av| 天天操夜夜撸| 国内老熟妇对白HDXXXX| 亚洲黄片免费| 蜜桃秘av一区二区三区安全| 国产专区在线| 亚洲成人视频免费观看| 伊人激情五月天| 91成人一区二区三区| 91乱子伦国产乱子伦海的味道| 人人草在线视频| 午夜成人在线观看| av黄色在线观看| 亚洲av观看| 国产传媒在线观看| 欧美精产国品一二三| 欧美一区二区在线观看| 亚洲一区二区三区无码| 无码国产精品一区二区三| 中文无码在线| 极品美女援交在线| AV狠狠干| 久久久综合网| 性性性性性XXXXX| 综合色五月| 无套内射在线| 中文字幕av免费在线观看| 福利无码| 中文字幕在线免费播放| 一本一道伊人99久久综| 古装一级无遮挡A片| 在线免费观看黄色电影| 日韩AV无码电影| 在线观看黄| 日韩人妻无码专区一区二区| 精品看片| 日本一区二区三区四区在线观看 | 中文字幕777| 91女人18毛片水多的意思 | 人人澡人人妻人人爽| 中文字幕成人网站中文字幕| 黄色小电影在线观看| 无码精品一区| 欧美综合网在线观看| 国产精品色婷婷| 超碰人妻人人操| 国产亚洲欧美视频| 亚洲福利视频网站| 一级日逼视频| 喷水在线观看| 色哟哟一区二区三区| 一区二区三区在线观看| 午夜福利啪啪啪| 欧美久色| 风间由美大荫蒂无码AV| 一级二级三级视频| 人人爽人人| 色女人天堂| 亚洲乱伦| 大香蕉操B| 日韩在线二区| 91无码秘蜜桃一区二区三区-百度| 色婷婷在线观看视频| 婷婷五月天在线播放| 手机看片福利| 国产精品女人精品久久久天天| 黄色国产在线| 91精品无码一区二区| 婷婷综合五月天| 瑟瑟视频在线观看| 激情麻豆论坛| 国产区视频| 伊香蕉大综综综合| 无卡无码| 中文字幕有码视频| 牛牛精品视频一区二区| 色操逼网| 国产三级片在线观看视频| 夜夜狠狠躁日日躁| 蜜臀AV在线| 亚洲中文无码在线观看| 北条麻妃一区二区三区在线播放| 囯产精品久久久久久久久久辛辛| 日韩在线毛片| 国产操逼免费看| 欧美成人网址在线观看| 黄片无遮挡| 欧美成人a| 亚洲一级黄| 日韩做爱| 色婷婷一二三精品A片| 国内自拍av| 蝌蚪窝视频在线观看| 久久久久久久三级片| av六月天| 国产毛片毛片毛片| 日韩成人网站| 制服.丝袜.亚洲.中文.豆花 | 女女久久| 依人大香蕉| 97精品| 亚洲无码成人AV| 91精片| 黄色电影A片| 无毛片| 97国产精品久久| 亚洲无码视频网站| 色999在线播放视频| 视色AV| 天天摸夜夜操| 香蕉黄色三级片| 天天干天天肏| 亚洲无码大全| 97视频| 精品一区二区三区四区五区| 亚洲激情四射| 爱爱导航| 天堂va欧美ⅴa亚洲va一夜| 成人做爰69片免费观看| www.zaixianshipin | 91香蕉视频在线看| 51国产黑料吃瓜在线入口| 欧美一区二区在线| 日韩无码2024| 日本高清无码视频| 大屌色片| 免费在线看A| 亚洲成人视屏| AAA级片| 人人做人人操| 免费观看无码视频| 三级操逼| 亚洲AV无码乱码国产精品蜜芽| 日韩国产欧美精品一区| 亚洲精品国产精品国自产| 东京热视频一区| 日韩欧美中文在线观看| 久久精品苍井空免费一区二 | 久久久久久久久久久久高清毛片一级 | 日本日韩欧美| 成人免费av| 国产91福利| 久久无码影视| 亚洲成年人在线| 精品天堂| 特级西西444www高清大胆免费看| 北条麻妃在线一区| 欧美综合亚洲图片综合区| 日本黄色电影在线观看| 国产无码激情视频| 2021国产精品视频| 丰满少妇一区二区三区| 天天综合字幕一区二区| 91AV免费观看| 午夜亚洲国产一区视频网站| 国产毛片一区| 91在线无码精品秘国产色多多 | 18成人在线观看| 国产区AV| 五月天婷婷AV| 嫩草视频网站| 麻豆MD传媒MD0071| av网站在线免费观看| AV大香蕉| 中文字幕35页| 2025精品精品视频| 黄色a级片| 丁香六月婷婷久久综合| 蜜桃成人无码区免费视频网站| 四虎永久www成人影院| 欧美亚洲国产视频| 水蜜桃视频在线观看| 日韩,变态,另类,中文,人妻| 国产色视频| 无码视频在线免费播放| 九九热在线视频| 91在线视频免费| 69av视频| 国产av网站大全| 人人操人人妻| 黑人巨粗进入疼哭A片| 欧美性视频网站| 亚洲午夜精品视频| 欧美亚洲三级片| 先锋影音资源网站| 色五月视频在线| 正在播放JUQ-878木下凛凛子| 高清无码网| 俺也去av| www.99热视频| 国产一级a毛一级a| 一本无码高清| 草比网| 深夜福利18| 91美女操逼视频| 国产成人精品一区二区三区| 中文一区在线观看| 欧美亚洲一区| 欧美国产综合| 大鸡巴日| 在线播放一区| 97在线资源| 国产有码| 成人91视频| 成人社区视频| 亚洲第一免费视频| 人妻综合第一页| 黄色视频网站免费观看| 国产精品久久久久久无码人妻| 怡春院熟女精品AV| 亚洲A级片| 国产精品久久在线| 欧美黄色网| 国产多人搡BBBB槡BBBB| 黄色av免费看| 成人AV免费在线观看| 中文字幕av久久爽爽| 大地影院在线资源观看| 中文字幕亚洲视频在线观看| 艹逼电影| 在线无码视频播放| 9久久精品| 欧美18禁黄免费网站| 激情五月天网址| 久久国产热| 日韩三区| 巜痴漢電車~凌脔版2| 久久视频99| 欧美伊人| 91亚洲精品乱码久久久久久蜜桃| 人人妻人人操人人干| 夜夜骚精品人妻av一区| 欧美性综合| 精品久久无码| 东京热综合影院| 中日韩在线视频| 夜夜嗨AV| 西西www444无码免费视频| 乱伦三级| 国产乱子伦-区二区三区熟睡91 | www免费视频在线观看播放| 日韩人妻精品一区二区| 日韩一级a片| 逼特逼视频在线| 丁香五月激情啪啪| 大香蕉国产| 波多野在线视频| 色网站操逼| 欧美喷水视频| 亚洲中文无码在线| 怮交小拗女小嫩苞视频| 欧美日韩国产91| 欧美黄片AAA| 久久久久久亚洲Av无码精品专口| 在线观看的av网站| 亚洲熟妇在线观看一区二区| 日韩视频播放在线综合| 免费的A片| 一区二区三区四区五区无码| 亚洲日本中文字幕在线观看| 蜜桃黄片AV在线观看| 国产成人av在线| www.插插| 日韩成人AV电影| 天天爽爽爽爽爽成人片| 天天干天天干天天日| 91jiujiu| 亚洲精品国产精品国自产网站 | 亚洲无码播放| 乱子伦】国产精品| 欧美在线大香蕉| 91久久超碰| 韩国成人无码视频| 91免费在线| 午夜高清无码视频| 二区三区免费视频| 亚洲无码。| 精品视频久久久久久| 爽好紧别夹喷水欧美| 美女自慰网站在线观看| 国产精品不卡一区二区三区| 高潮国产| 中午字幕在线观看| 三级网站在线| 国产suv精品一区二区| 婷婷高清无码| 亚洲区一区二| 51一区二区三区| 91视频在线观看18| 日本无码一区二区三区| 蜜桃av秘无码一区二区三欧| AV天堂电影网| 二区三区视频| 久久久久国产精品视频| 午夜做爱福利视频| 日韩成人视频在线观看| www中文字幕| 很很干在线视频| 国内自拍偷拍视频| 国产成人秘在线观看免费网站| 一区二区三区三级片| 99精品六月婷婷综合在线 | 五月激情综合| 三级黄色毛片| 一道本无码在线观看| 丁香六月久久| 久久免费视频3| 久久综合伊人7777777| 18sav| 成人性生活一级片| 丁香五月在线观看| 日本免费黄色电影| 国产理论电影在线观看| 国产精品99久久久久久成人| 欧美性爱怡红院| 草逼视频免费看| 久久成人在线| 日韩成人无码电影网站| 人人操天天干| 天堂网中文在线| 亚洲国产精品成人va在线观看| 欧美色色网| 少妇一区二区三区| 日本日韩欧美| 国产AV三级片| www.99爱| 麻豆mdapp03.tⅴ| 成人无码区免费| 成人欧美视频| 日本五十路熟女视频| 久草在线播放| 成人性爱在线播放| a久久| aaa成人| 亚洲精品国产AV婷婷| 五月天丁香花| 亚洲色图自拍| 日韩不卡一区二区三区| 国产精品一区二区在线播放 | 大香煮伊在75| 色色色999| 欧美作爱| 97无码人妻一区二区三区| 成人黄网在线观看| 水多多成人网站A片| 日本女人高潮视频| 很色很黄的A片一| 伊人色爱| 亚洲欧美婷婷五月色综合| 中字av| 久久九九视频| 日本日逼网| 秋霞午夜久久| 免费在线观看Av| 亚洲日逼网| 精东av| 12——13女人毛片毛片| 国产精品久久久久久无码人妻| 高清无码免费看| 无码在线观看免费视频| 久久久8| 五月丁香成人| 一级欧美视频| av不卡在线| aⅴ视频| 无码中文字幕在线观看| 日韩精品在线视频| 最新AV在线播放| 影音先锋无码一区| 免费看黄色大全| 人妻综合第一页| 怡春院在线视频|