久久精品国产精品国产精品污,男人扒开添女人下部免费视频,一级国产69式性姿势免费视频,夜鲁夜鲁很鲁在线视频 视频,欧美丰满少妇一区二区三区,国产偷国产偷亚洲高清人乐享,中文 在线 日韩 亚洲 欧美,熟妇人妻无乱码中文字幕真矢织江,一区二区三区人妻制服国产

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Winsock编程宝典(转帖)

發(fā)布時間:2025/3/14 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Winsock编程宝典(转帖) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

--簡單的 Winsock 應(yīng)用程式設(shè)計

TCP連接建立與關(guān)閉

相信各位讀者現(xiàn)在對於 Winsock 的定義、系統(tǒng)環(huán)境,以及一些 Winsock Stack及 Winsock 應(yīng)用程式,都有基本的認識了。接下來筆者希望能分幾期為各位讀者介紹一下簡單的 Winsock 網(wǎng)路應(yīng)用程式設(shè)計。我們將以 Winsock 1.1 規(guī)格所定義的 46 個應(yīng)用程式介面(API)為基礎(chǔ),逐步來建立一對 TCP socket 主從架構(gòu)(Client / Server)的程式。在這兩個程式中,Server 將使用 Winsock 提供的「非同步」(asynchronous)函式來建立 socket 連結(jié)、關(guān)閉、及資料收送等等;而 Client 則采類似傳統(tǒng) UNIX 的「阻攔式」(blocking)。由於我們的重點并不在於 MS Windows SDK 的程式設(shè)計,所以我們將使用最簡便的方式來顯示訊息;有關(guān) MS Windows 程式的技巧,請各位讀者自行研究相關(guān)的書籍及文章。

今天我們先要看一下主從架構(gòu) TCP socket 的建立連結(jié)(connect)及關(guān)閉(close)。以前筆者曾簡單地介紹過主從架構(gòu)的概念,現(xiàn)在我們再以生活上更淺顯的例子來說明一下,讀者稍後也較容易能明白筆者的敘述。我們可以假設(shè) Server 就像是電信局所提供的一些服務(wù),比如「104 查號臺」或「112 障礙臺」。

(1)電信局先建立好了一個電話總機,這就像是呼叫 socket() 函式開啟了一個 socket。

(2)接著電信局將這個總機的號碼定為 104,就如同我們呼叫 bind() 函式,將 Server 的這個 socket 指定(bind)在某一個 port。當(dāng)然電信局必須讓用戶知道這個號碼;而我們的 Client 程式同樣也要知道 Server 所用的 port,待會才有辦法與之連接。

(3)電信局的 104 查號臺底下會有一些自動服務(wù)的分機,但是它的數(shù)量是有限的,所以有時你會撥不通這個號碼(忙線)。同樣地,我們在建立一個 TCP 的Server socket 時,也會呼叫 listen() 函式來監(jiān)聽等待;listen() 的第二個參數(shù)即是 waiting queue 的數(shù)目,通常數(shù)值是由 1 到 5。(事實上這兩者還是有點不一樣。)

(4)用戶知道了電信局的這個 104 查號服務(wù),他就可以利用某個電話來撥號連接這個服務(wù)了。這就是我們 Client 程式開啟一個相同的 TCP socket,然後呼叫 connect() 函式去連接 Server 指定的那個 port。當(dāng)然了,和電話一樣,如果 waiting queue 滿了、與 Server 間線路不通、或是 Server 沒提供此項服務(wù)時,你的連接就會失敗。

(5)電信局查號臺的總機接受了這通查詢的電話後,它會轉(zhuǎn)到另一個分機做服務(wù),而總機本身則再回到等待的狀態(tài)。Server 的 listening socket 亦是一樣,當(dāng)你呼叫了 accept() 函式之後,Server 端的系統(tǒng)會建立一個新的 socket 來對此連接做服務(wù),而原先的 socket 則再回到監(jiān)聽等待的狀態(tài)。

(6)當(dāng)你查詢完畢了,你就可以掛上電話,彼此間也就離線了。Client和Server間的 socket 關(guān)閉亦是如此;不過這個關(guān)閉離線的動作,可由 Client 端或Server 端任一方先關(guān)閉。有些電話查詢系統(tǒng)不也是如此嗎?

接下來,我們就來看主從架構(gòu)的 TCP socket 是如何利用這些 Winsock 函式來達成的;并利用資策會資訊技術(shù)處的「WinKing」這個 Winsock Stack 中某項功能來顯示 sockets 狀態(tài)的變化。文章中僅列出程式的片段,完整的程式請看附錄的程式。

Server進入監(jiān)聽狀態(tài)

首先我們先看 Server 端如何建立一個 TCP socket,并使其進入監(jiān)聽等待的狀態(tài)。在圖 1. 上,我們可以看到最先被呼叫到的是 WSAStartup() 函式。

WSAStartup

格 式: int PASCAL FAR WSAStartup( WORD wVersionRequested, LPWSADATA lpWSAData );

參 數(shù): wVersionRequested 欲使用的 Windows Sockets API 版本

lpWSAData 指向 WSADATA 資料的指標(biāo)

傳回值: 成功 – 0

失敗 - WSASYSNOTREADY / WSAVERNOTSUPPORTED / WSAEINVAL

說明: 此函式「必須」是應(yīng)用程式呼叫到 Windows Sockets DLL 函式中的第一個,也唯有此函式呼叫成功後,才可以再呼叫其他 Windows Sockets DLL 的函式。此函式亦讓使用者可以指定要使用的 Windows Sockets API 版本,及獲取設(shè)計者的一些資訊。程式中我們要用 Winsock 1.1,所以我們在程式中有一段為:

WSAStartup((WORD)((1<<8)|1),(LPWSADATA) &WSAData)

其中 ((WORD)((1<<8)|1) 表示我們要用的是 Winsock 「1.1」版本,而WSAData 則是用來儲存由系統(tǒng)傳回的一些有關(guān)此一 Winsock Stack 的資料。

socket

再來我們呼叫 socket() 函式來開啟 Server 端的 TCP socket。 socket():建立Socket。

格 式: SOCKET PASCAL FAR socket( int af, int type, int protocol );

參 數(shù): af 目前只提供 PF_INET(AF_INET)

type Socket 的型態(tài) (SOCK_STREAM、SOCK_DGRAM)

protocol 通訊協(xié)定(如果使用者不指定則設(shè)為0)

傳回值: 成功 - Socket 的識別碼

失敗 - INVALID_SOCKET(呼叫 WSAGetLastError() 可得知原因)

說明: 此函式用來建立一 Socket,并為此 Socket 建立其所使用的資源。Socket 的型態(tài)可為 Stream Socket 或 Datagram Socket。我們要建立的是 TCP socket,所以程式中我們的第二個參數(shù)為SOCK_STREAM,我們并將開啟的這個 socket 號碼記在 listen_sd 這個變數(shù)。

listen_sd = socket(PF_INET, SOCK_STREAM, 0)

bind

接下來我們要指定一個位址及 port 給 Server 的這個 socket,這樣 Client 才知道待會要連接哪一個位址的哪個 port;所以我們呼叫 bind() 函式。

bind():指定 Socket 的 Local 位址 (Address)。

格式:

int PASCAL FAR bind( SOCKET s, const struct sockaddr FAR *name,int namelen );

參數(shù):

s: Socket的識別碼

name: Socket的位址值

namelen: name的長度

傳回值: 成功 – 0

失敗 - SOCKET_ERROR (呼叫 WSAGetLastError() 可得知原因)

說明: 此一函式是指定 Local 位址及 Port 給某一未定名之 Socket。使用者若不在意位址或 Port 的值,那麼他可以設(shè)定位址為 INADDR_ANY,及 Port 為 0;那麼Windows Sockets 會自動將其設(shè)定適當(dāng)之位址及 Port (1024 到 5000之間的值),使用者可以在此 Socket 真正連接完成後,呼叫 getsockname() 來獲知其被設(shè)定的值。bind() 函式要指定位址及 port,這個位址必須是執(zhí)行這個程式所在機器的 IP位址,所以如果讀者在設(shè)計程式時可以將位址設(shè)定為 INADDR_ANY,這樣Winsock 系統(tǒng)會自動將機器正確的位址填入。如果您要讓程式只能在某臺機器上執(zhí)行的話,那麼就將位址設(shè)定為該臺機器的 IP 位址。由於此端是 Server 端,所以我們一定要指定一個 port 號碼給這個 socket。讀者必須注意一點,TCP socket 一旦選定了一個位址及 port 後,就無法再呼叫另一次 bind 來任意更改它的位址或 port。在程式中我們將 Server 端的 port 指定為 7016,位址則由系統(tǒng)來設(shè)定。

struct sockaddr_in sa;

sa.sin_family = PF_INET;

sa.sin_port = htons(7016); //port number

sa.sin_addr.s_addr = INADDR_ANY;//address

bind(listen_sd, (struct sockaddr far *)&sa, sizeof(sa))

我們在指定 port 號碼時會用到 htons() 這個函式,主要是因為各機器的數(shù)值讀取方式不同(PC與UNIX系統(tǒng)即不相同),所以我們利用這個函式來將 host order 的排列方式轉(zhuǎn)換成 network order 的排列方式;相同地,我們也可以呼叫ntohs() 這個相對的函式將其還原。

host order各機器不同,但network order都相同;htons是針對short數(shù)值,對於long數(shù)值則用hotnl及ntohl。

listen

指定完位址及 port 之後,我們呼叫 listen() 函式,讓這個 socket 進入監(jiān)聽狀態(tài)。一個 Server 端的 TCP socket 必須在做完了 listen 的呼叫後,才能接受 Client 端的連接。

格式:

int PASCAL FAR listen( SOCKET s, int backlog );

參數(shù):

s: Socket 的識別碼

backlog: 未真正完成連接前(尚未呼叫 accept 前)彼端的連接要求的最大個數(shù)

傳回值:

成功 – 0

失敗 - SOCKET_ERROR (呼叫 WSAGetLastError() 可得知原因)

說明: 使用者可利用此函式來設(shè)定 Socket 進入監(jiān)聽狀態(tài),并設(shè)定最多可有多少個在未真正完成連接前的彼端的連接要求。(目前最大值限制為 5, 最小值為1)程式中我們將 backlog 設(shè)為 1 。

listen(listen_sd, 1)

呼叫完 listen 後,此時 Client 端如果來連接的話,Client 端的連接動作(connect)會成功,不過此時 Server 端必須再呼叫 accept() 函式,才算正式完成Server 端的連接動作。但是我們什麼時候可以知道 Client 端來連接,而適時地呼叫 accept 呢?在這里我們就要利用 WSAAsyncSelect 函式,將Server 端的這個 socket 轉(zhuǎn)變成 Asynchronous 模式,讓系統(tǒng)主動來通知我們有Client 要連接了。

WSAAsyncSelect

格式:

int PASCAL FAR WSAAsyncSelect( SOCKET s, HWND hWnd, unsigned int wMsg, long lEvent );

參數(shù):

s: Socket 的編號

hWnd: 動作完成後,接受訊息的視窗 handle

wMsg: 傳回視窗的訊息

lEvent: 應(yīng)用程式有興趣的網(wǎng)路事件

傳回值:

成功 – 0

失敗 - SOCKET_ERROR (呼叫 WSAGetLastError() 可得知原因)

說明:此函式是讓使用者用來要求 Windows Sockets DLL 在偵測到某一 Socket有網(wǎng)路事件時送訊息到使用者指定的視窗;網(wǎng)路事件是由參數(shù) lEvent 設(shè)定。呼叫此函式會主動將該 Socket 設(shè)定為 Non-blocking 模式。lEvent 的值可為以下之「OR」組合:(參見 WINSOCK第1.1版88、89頁) FD_READ、FD_WRITE、FD_OOB、FD_ACCEPT、FD_CONNECT、FD_CLOSE 使用者若是針對某一Socket再次呼叫此函式時,會取消對該 Socket 原先之設(shè)定。若要取消對該Socket 的所有設(shè)定,則 lEvent 的值必須設(shè)為 0。我們在程式中要求 Winsock 系統(tǒng)知道 Client 要來連接時,送一個ASYNC_EVENT 的訊息到程式中 hwnd 這個視窗;由於我們想知道的只有 accept事件,所以我們只設(shè)定 FD_ACCEPT。

WSAAsyncSelect(listen_sd, hwnd, ASYNC_EVENT, FD_ACCEPT)

讀者必須注意一點,WSAAsyncSelect 的設(shè)定是針對「某一個 socket」;也就是說,只有當(dāng)您設(shè)定的這個 socket (listen_sd)的那些事件(FD_ACCEPT)發(fā)生時,您才會收到這個訊息(ASYNC_EVENT)。如果您開啟了很多 sockets,而要讓每個 socket 都變成 asynchronous 模式的話,那麼就必須對「每一個 socket」都呼叫 WSAAsyncSelect 來一一設(shè)定。而如果您想將某一個 socket 的 async 事件通知設(shè)定取消的話,那麼同樣也是用 WSAAsyncSelect 這個函式;且第四個參數(shù)lEvent 一定要設(shè)為 0。

WSAAsyncSelect( s, hWnd, 0, 0 ) -- 取消所有 async 事件設(shè)定

呼叫 WSAAsyncSelect 的同時也將此socket改變成「非阻攔」(non-blocking)模式。但是此時這個 socket 不能很簡單地用 ioctlsocket() 這個函式就將它再變回「阻攔」(blocking)模式。也就是說WSAAsyncSelect 和 ioctlsocket 所改變的「非阻攔」模式仍是有些不同的。如果您想將一個「非同步」(asynchronous)模式的 socket 再變回「阻攔」模式的話,必須先呼叫 WSAAsyncSelect() 將所有的 async 事件取消,再用 ioctlsocket() 將它變回阻攔模式。

ioctlsocket

ioctlsocket():控制 Socket 的模式。

格 式: int PASCAL FAR ioctlsocket( SOCKET s, long cmd, u_long FAR * argP );

參 數(shù): s Socket 的識別碼

cmd 指令名稱

argP 指向 cmd 參數(shù)的指標(biāo)

傳回值: 成功 – 0

失敗 - SOCKET_ERROR (呼叫 WSAGetLastError() 可得知原因)

說明: 此函式用來獲取或設(shè)定 Socket 的運作參數(shù)。其所提供的指令有:(參見WINSOCK 第 1.1 版 35、36 頁) cmd 的值可為:

FIONBIO -- 開關(guān) non-blocking 模式//允許或禁止套接字的非阻塞模式,允許為非0,禁止為0

FIONREAD -- Socket一次可讀取的資料量(目前 in buffer 的資料量//確定套接字自動讀入的數(shù)據(jù)量

SIOCATMARK -- OOB 資料是否已被讀取完//確定是否所有帶外數(shù)據(jù)都已被讀入

由於我們 Server 端的 socket 是用非同步模式,且設(shè)定了 FD_ACCEPT 事件,所以當(dāng) Client 端和我們連接時,Winsock Stack 會主動通知我們;我們再先來看看Client 端要如何和 Server 端建立連接?

Client主動建立連接

Client 首先也是呼叫 WSAStartup() 函式來與 Winsock Stack 建立關(guān)系;然後同樣呼叫 socket() 來建立一個 TCP socket。(讀者此時一定要用 TCP socket 來連接Server 端的 TCP socket,而不能用 UDP socket 來連接;因為相同協(xié)定的 sockets 才能相通,TCP 對 TCP,UDP 對 UDP)和 Server 端的 socket 不同的地方是:Client 端的 socket 可以呼叫 bind()函式,由自己來指定 IP 位址及 port 號碼;但是也可以不呼叫 bind(),而由 Winsock Stack來自動設(shè)定 IP 位址及 port 號碼(此一動作在呼叫 connect() 函式時會由 Winsock 系統(tǒng)來完成)。通常我們是不呼叫 bind(),而由系統(tǒng)設(shè)定的,稍後可呼叫g(shù)etsockname() 函式來檢查系統(tǒng)幫我們設(shè)定了什麼 IP 及 port。一般言,系統(tǒng)會自動幫我們設(shè)定的 port 號碼是在 1024 到 5000 之間;而如果讀者要自己用 bind設(shè)定 port的話,最好是 5000 以上的號碼。

connect():要求連接某一 TCP Socket 到指定的對方。

格 式: int PASCAL FAR connect( SOCKET s, const struct sockaddr FAR *name, int namelen );

參 數(shù): s Socket 的識別碼

name 此 Socket 想要連接的對方位址

namelen name的長度

傳回值: 成功 – 0

失敗 - SOCKET_ERROR (呼叫WSAGetLastError()可得知原因)

說明: 此函式用來向?qū)Ψ揭蠼⑦B接。若是指定的對方位址為 0 的話,會傳回錯誤值。當(dāng)連接建立完成後,使用者即可利用此一 Socket 來做傳送或接收資料之用了。

我們的例子中, Client 是要連接的是自己機器上 Server 所監(jiān)聽的 7016 這個port,所以我們有以下的程式片段。(假設(shè)我們機器的 IP 存在my_host_ip)

struct sockaddr_in sa; /* 變數(shù)宣告 */
sa.sin_family = PF_INET; /* 設(shè)定所要連接的 Server 端資料 */

sa.sin_port = htons(7016);

sa.sin_addr.s_addr = htonl(my_host_ip);

connect(mysd, (struct sockaddr far *)&sa, sizeof(sa)) /* 建立連接 */

Server接受連接

由於我們 Server 端的 socket 是設(shè)定為「非同步模式」,且是針對 FD_ACCEPT這個事件,所以當(dāng) Client 來連接時,我們 Server 端的 hwnd 這個視窗會收到Winsock Stack 送來的一個 ASYNC_EVENT 的訊息。(參見前面 WSAAsyncSelect 的設(shè)定)這時,我們應(yīng)該先利用 WSAGETSELECTERROR(lParam) 來檢查是否有錯誤;并由 WSAGETSELECTEVENT(lParam) 得知是什麼事件發(fā)生(因為WSAAsyncSelect 函式可針對同一個 socket 同時設(shè)定很多事件,但是只用一個訊息來代表)(此處當(dāng)然是 FD_ACCEPT 事件);然後再呼叫相關(guān)的函式來處理此一事件。所以我們呼叫 accept() 函式來建立 Server 端的連接。

accept():接受某一 Socket 的連接要求,以完成 Stream Socket 的連接。

格 式: SOCKET PASCAL FAR accept( SCOKET s, struct sockaddr FAR *addr, int FAR *addrlen );

參 數(shù): s Socket的識別碼

addr 存放來連接的彼端的位址

addrlen addr的長度

傳回值:成功 - 新的Socket識別碼

失敗 - INVALID_SOCKET (呼叫 WSAGetLastError() 可得知原因)

說明: Server 端之應(yīng)用程式呼叫此一函式來接受 Client 端要求之 Socket 連接動作;如果Server 端之 Socket 是為 Blocking 模式,且沒有人要求連接動作,那麼此一函式會被 Block 住;如果為 Non-Blocking 模式,此函式會馬上回覆錯誤。accept()函式的答覆值為一新的 Socket,此新建之 Socket 不可再用來接受其它的連接要求;但是原先監(jiān)聽之 Socket 仍可接受其他人的連接要求。

TCP socket 的 Server 端在呼叫 accept() 後,會傳回一個新的 socket 號碼;而這個新的 socket 號碼才是真正與 Client 端相通的 socket。比如說,我們用socket() 建立了一個 TCP socket,而此 socket 的號碼(系統(tǒng)給的)為 1,然後我們呼叫的bind()、listen()、accept() 都是針對此一 socket;當(dāng)我們在呼叫 accept()後,傳回值是另一個 socket 號碼(也是系統(tǒng)給的),比如說 3;那麼真正與 Client 端連接的是號碼 3 這個 socket,我們收送資料也都是要利用 socket 3,而不是 socket 1;讀者不可搞錯。我們在程式中對 accept() 的呼叫如下;我們并可由第二個參數(shù)的傳回值,得知究竟是哪一個 IP 位址及 port 號碼的 Client 與我們 Server 連接。

struct sockaddr_in sa;

int sa_len = sizeof(sa);

my_sd = accept(listen_sd, (struct sockaddr far *)&sa, &sa_len)

當(dāng) Server 端呼叫完 accept() 後,主從架構(gòu)的 TCP socket 連接才算真正建立完畢; Server 及 Client 端也就可以分別利用此一 socket 來送資料到對方或收對方送來的資料了。

Server/Client結(jié)束連接

最後我們來看一下如何結(jié)束 socket 的連接。socket 的關(guān)閉很簡單,而且可由Server 或 Client 的任一端先啟動,只要呼叫 closesocket() 就可以了。而要關(guān)閉監(jiān)聽狀態(tài)的 socket,同樣也是利用此一函式。

closesocket():關(guān)閉某一Socket。

格 式: int PASCAL FAR closesocket( SOCKET s );

參 數(shù): s Socket 的識別碼

傳回值: 成功 – 0

失敗 - SOCKET_ERROR (呼叫 WSAGetLastError() 可得知原因)

說明: 此一函式是用來關(guān)閉某一 Socket。若是使用者原先對要關(guān)閉之 Socket 設(shè)定 SO_DONTLINGER,則在呼叫此一函式後,會馬上回覆,但是此一 Sokcet 尚未傳送完畢的資料會繼續(xù)送完後才關(guān)閉。若是使用者原先設(shè)定此 Socket 為 SO_LINGER,則有兩種情況:

(a) Timeout 設(shè)為 0 的話,此一 Socket 馬上重新設(shè)定 (reset),未傳完或未收到的資料全部遺失。

(b) Timeout 不為 0 的話,則會將資料送完,或是等到 Timeout 發(fā)生後才真正關(guān)閉。

程式結(jié)束前,讀者們可千萬別忘了要呼叫 WSACleanup() 來通知 WinsockStack;如果您不呼叫此一函式,Winsock Stack 中有些資源可能仍會被您占用而無法清除釋放喲。

WSACleanup():結(jié)束 Windows Sockets DLL 的使用。

格 式: int PASCAL FAR WSACleanup( void );

參 數(shù): 無

傳回值: 成功 – 0

失敗 - SOCKET_ERROR (呼叫 WSAGetLastError() 可得知原因)

說明: 應(yīng)用程式在使用 Windows Sockets DLL 時必須先呼叫WSAStartup() 來向 Windows Sockets DLL 注冊;當(dāng)應(yīng)用程式不再需要使用Windows Sockets DLL 時,須呼叫此一函式來注銷使用,以便釋放其占用的資源。

結(jié)語

這期筆者先介紹主從架構(gòu) TCP sockets 的連接及關(guān)閉,以後會再陸續(xù)介紹如何收送資料,以及其他 API 的使用。想要進一步了解如何撰寫 Winsock 程式的讀者,可以好好研究一下筆者 demoserv 及 democlnt 這兩個程式;也許不是寫的很好,但是希望可以帶給不懂 Winsock 程式設(shè)計的人一個起步。讀者們亦可自行用 anonymous ftp 方式到 SEEDNET 臺北主機 tpts1.seed.net. tw(139.175.1.10)的 UPLOAD / WINKING 目錄下,取得筆者與陳建伶小姐所設(shè)計的WinKing 這個 Winsock Stack 的試用版,來跑 demoserv 與 democlnt 這兩個程式及其他許許多多的 Winsock 應(yīng)用程式。(正式版本請洽 SEEDNET 服務(wù)中心,新版的WinKing 已含 Windows 撥接及 PPP 程式,適合電話撥接用戶在 Windows 環(huán)境下用 SEEDNET;WinKing 同樣也提供 Ethernet 環(huán)境的使用。)

收送資料

在前一期的文章中,筆者為大家介紹了如何在 Winsock 環(huán)境下建立主從架構(gòu)(Client/Server)的 TCP socket 的連接建立與關(guān)閉;今天筆者將繼續(xù)為大家介紹如何利用 TCP socket 來收送資料,并詳細解說 WSAAsyncSelect 函式中的FD_READ 及 FD_WRITE 事件。相信讀者們已經(jīng)知道 TCP socket 的連接是在 Client 端呼叫 connect 函式成功,且 Server 端呼叫 accept 函式後,才算完全建立成功;當(dāng)連接建立成功後, Client 及 Server 也就可以利用這個連接成功的 socket 來傳送資料到對方,或是收取對方送過來的資料了。在介紹資料的收送前,筆者先介紹一下 TCP socket 與 UDP socket 在傳送資料時的特性:

2 Stream (TCP) Socket 提供「雙向」、「可靠」、「有次序」、「不重覆」之資料傳送。

2 Datagram (UDP) Socket 則提供「雙向」之溝通,但沒有「可靠」、「有次序」、「不重覆」等之保證;所以使用者可能會收到無次序、重覆之資料,甚至資料在傳輸過程中也可能會遺漏。由於 UDP Socket 在傳送資料時,并不保證資料能完整地送達對方,所以我們常用的一些應(yīng)用程式(如 telnet、mail、ftp、news...等)都是采用 TCP Socket,以保證資料的正確性。

TCP 及 UDP Socket 都是雙向的,所以我們是利用同一個 Socket 來做傳送及收取資料的動作;一般言 TCP Socket 的資料送、收是呼叫 send 及 recv這兩個函式來達成,而 UDP Socket 則是用 sendto 及 recvfrom 這兩個函式。不過TCP Socket 也可用 sendto 及 recvfrom 函式,UDP Socket 同樣可用 send 及recv 函式;這一點我們稍後再加以解釋。現(xiàn)在我們先看一下 send 及 recv 的函式說明,并回到我們的前一期程式。

◎ send():使用連接式(connected)的 Socket 傳送資料。

格 式: int PASCAL FAR send( SOCKET s, const char FAR *buf, int len, int flags );

參 數(shù): s Socket 的識別碼

buf 存放要傳送的資料的暫存區(qū)

len buf 的長度

flags 此函式被呼叫的方式

傳回值:成功 - 送出的資料長度

失敗 - SOCKET_ERROR (呼叫 WSAGetLastError() 可得知原因)

說明: 此函式適用於連接式的 Datagram 或 Stream Socket 來傳送資料。 對Datagram Socket 言,若是 datagram 的大小超過限制,則將不會送出任何資料,并會傳回錯誤值。對 Stream Socket 言,Blocking 模式下,若是傳送 (transport) 系統(tǒng)內(nèi)之儲存空間(output buffer)不夠存放這些要傳送的資料,send 將會被 block住,直到資料送完為止;如果該 Socket 被設(shè)定為 Non-Blocking 模式,那麼將視目前的 output buffer 空間有多少,就送出多少資料,并不會被 block 住。使用者亦須注意 send 函式執(zhí)行完成,并不表示資料已經(jīng)成功地送抵對方了,而是已經(jīng)放到系統(tǒng)的 output buffer 中等待被送出。flags 的值可設(shè)為 0 或 MSG_DONTROUTE及 MSG_OOB 的組合。(參見 WINSOCK第1.1版48頁)

◎ recv():自 Socket 接收資料。

格 式: int PASCAL FAR recv( SOCKET s, char FAR *buf, int len, int flags );

參 數(shù): s Socket 的識別碼

buf 存放接收到的資料的暫存區(qū)

len buf 的長度

flags 此函式被呼叫的方式

傳回值:成功 - 接收到的資料長度 (若對方 Socket 已關(guān)閉,則為 0)

失敗 - SOCKET_ERROR (呼叫 WSAGetLastError() 可得知原因)

說明: 此函式用來自連接式的 Datagram Socket 或 Stream Socket 接收資料。對 Stream Socket 言,我們可以接收到目前 input buffer 內(nèi)有效的資料,但其數(shù)量不超過 len 的大小。若是此 Socket 設(shè)定 SO_OOBINLINE,且有 out-of-band 的資料未被讀取,那麼只有 out-of-band 的資料被取出。對 Datagram Socket 言,只取出第一個 datagram;若是該 datagram 大於使用者提供的儲存空間,那麼只有該空間大小的資料被取出,多馀的資料將遺失,且回覆錯誤的訊息。另外如果 Socket為 Blocking 模式,且目前 input buffer 內(nèi)沒有任何資料,則 recv() 將 block 到有任何資料到達為止;如果為 Non-Blocking 模式,且 input buffer 無任何資料,則會馬上回覆錯誤。參數(shù) flags 的值可為 0 或 MSG_PEEK、MSG_OOB 的組合; MSG_PEEK 代表將資料拷貝到使用者提供的 buffer,但是資料并不從系統(tǒng)的 input buffer 中移走;0 則表示拷貝并移走。(參考 WINSOCK 第1.1版41 頁)

Server收送及關(guān)閉Socket

在前一期中,建立的是一個 Asynchronous 模式的 Server,曾對listen_sd Socket呼叫 WSAAsyncSelect 函式,并設(shè)定FD_ACCEPT 事件,所以當(dāng) Client 與我們連接時,系統(tǒng)會傳給我們一個ASYNC_EVENT 訊息;我們在收到訊息并判斷是FD_ACCEPT 事件,於是呼叫 accept() 來建立連接。

my_sd = accept(listen_sd, (struct sockaddr far *)&sa, &sa_len)

在呼叫完 accept 函式,成功地建立了 Server 端與 Client 端的連接後,便可利用新建的 Socket(my_sd)來收送資料了。由於我們同樣希望用Asynchronous 的方式,因此要再利用 WSAAsyncSelect() 函式來幫新建的Socket 設(shè)定一些事件,以便事件發(fā)生時 Winsock Stack 能主動通知我們。由於我們的 Server 是被動的接受 Client 的要求,然後再做答覆,所以我們設(shè)定FD_READ 事件;我們也希望 Winsock Stack 在知道 Client 關(guān)閉 Socket 時,能主動通知我們,所以同時也設(shè)定 FD_CLOSE 事件。(讀者須注意,我們設(shè)定事件的 Socket 號碼是呼叫 accept 後傳回的新 Socket 號碼,而不是原先監(jiān)聽狀態(tài)的Socket 號碼)

WSAAsyncSelect(my_sd, hwnd, ASYNC_EVENT, FD_READ|FD_CLOSE)

在這里,我們同樣是利用 hwnd 這個視窗及 ASYNC_EVENT 這個訊息;在前文中,筆者曾告訴各位,在收到 ASYNC_EVENT 訊息時,我們可以利用WSAGETSELECTEVENT(lParam) 來判斷究竟是哪一事件(FD_READ 或FD_CLOSE)發(fā)生了;所以并不會混淆。那我們到底在什麼時候會收到FD_READ 或 FD_CLOSE 事件的訊息呢?

FD_READ 事件

我們會收到 FD_READ 事件通知我們?nèi)プx取資料的情況有:

(1)呼叫 WSAAsyncSelect 函式來對此 Socket 設(shè)定 FD_READ 事件時,input buffer 中已有資料。

(2)原先系統(tǒng)的 input buffer 是空的,當(dāng)系統(tǒng)再收到資料時,會通知我們。

(3)使用者呼叫 recv 或 recvfrom 函式,從 input buffer 讀取資料,但是并沒有一次將資料讀光,此時會再驅(qū)動一個 FD_READ 事件,表示仍有資料在input buffer 中。

讀者必須注意:如果我們收到 FD_READ 事件通知的訊息,但是我們故意不呼叫 recv 或 recvfrom 來讀取資料的話,爾後系統(tǒng)又收到資料時,并不會再次通知我們,一定要等我們呼叫了 recv 或 recvfrom 後,才有可能再收到FD_READ 的事件通知。

FD_CLOSE 事件

當(dāng)系統(tǒng)知道對方已經(jīng)將Socket關(guān)閉了的情況下(收到 FIN 通知,并和對方做關(guān)閉動作的 hand-shaking),我們會收到 FD_CLOSE 的事件通知,以便我們也能將這個相對的 Socket 關(guān)閉。FD_CLOSE 事件只會發(fā)生於 TCP Socket,因為它是 connection-oriented;對於 connectionless 的 UDP Socket,即使設(shè)了FD_CLOSE,也不會有作用的。

程式中,當(dāng) Client 端送一個要求(request)來時,系統(tǒng)會以ASYNC_EVENT 訊息通知我們的 hwnd 視窗;我們在利用WSAGETSELECTEVENT(lParam) 及 WSAGETSELECTERROR(lParam) 知道是FD_READ 事件及檢查無誤後,便呼叫 recv() 函式來收取 Client 端送來的資料。

recv(wParam, &data, sizeof(data), 0)

筆者在前一期文章中也曾提到說,FD_XXXX 事件發(fā)生,收到訊息時,視窗 handle 被呼叫時的參數(shù) wParam 代表的就是事件發(fā)生的 Socket 號碼,所以此處 wParam 的值也就是前面提到的 my_sd 這個 Socket 號碼。recv() 的第四個參數(shù)設(shè)為 0,表示我們要將資料從系統(tǒng)的 input buffer 中讀取并移走。收到要求後,我們要答覆 Client 端,也就是要送資料給 Client;這時我們就要利用 send 這個函式了。我們先將資料放到 data 這個資料暫存區(qū),然後呼叫 send 將它送出,我們利用的也是 wParam(my_sd) 這個同樣的 Socket 來做傳送的動作,因為它是雙向的。

send(wParam, &data, strlen(data), 0)

Server 與 Client 收送資料一段時間後(資料全部收送完畢),如果 Client 端先呼叫 closesocket 將它那端的 Socket 關(guān)閉,那麼系統(tǒng)在知道後,會通知我們一個 FD_CLOSE 事件的訊息,此時我們也可以呼叫 closesocket 將我們這端的Socket 關(guān)閉了;當(dāng)然我們也可以呼叫 closesocket 先主動關(guān)閉我們這端的Socket。

Client收送及關(guān)閉Socket

我們例子的 Client 是采 Blocking 模式,所以在呼叫 connect() 函式與 Server連接時,可能會等一下子才成功;connect() 函式返回後,且無錯誤發(fā)生的話,Client 與 Server 端的 TCP socket 連接就算成功了。這時,我們便可利用這個連接成功的 Socket 來送收資料了。由於我們并沒有要設(shè)定為 Asynchronous 模式,所以也不用呼叫 WSAAsyncSelect() 來設(shè)定事件。Client 端通常是會先主動發(fā)出要求到 Server 端,因此我們呼叫 send() 來傳送此一資料。我們的資料量很小,所以并不會被 send() 函式 Block 住;不過如果您要送的資料量很大,那麼可能會等一段時間才會自 send() 函式返回;也就是說必須等資料都放到系統(tǒng)的 output buffer 後才會返回;這是因為我們 Client的Socket 是阻攔模式。如果我們用的是非阻攔模式的 Socket,那麼 send() 函式會視系統(tǒng)的 output buffer 的空間有多少,只拷貝那麼多的資料到 output buffer,然後就返回,并告知使用者送出了多少資料,并不須等所有資料都放到 output buffer 才返回。我們將要求放在 data 資料暫存區(qū),然後呼叫 send() 將要求送出。資料送出後,我們呼叫 recv() 來等待 Server 端的答覆。

send(mysd, data, strlen(data), 0)

recv(mysd, &data, sizeof(data), 0)

由於我們 Client 端是 Blocking 模式,所以 recv() 會一直 Block 住,直到下列的情況之一發(fā)生,才會返回。

(1)Server 端送來資料。(此時 return 值是讀取的資料長度)

(2)Server 端將相對的 Socket 關(guān)閉了。(此時的 return 值會是 0)

(3)Client 端自己呼叫 WSACancelBlockingCall() 來取消 recv() 的呼叫。(此時 return 值是 SOCKET_ERROR 錯誤,錯誤碼 10004 WSAEINTR)

同樣地,資料全部送收完畢後,我們也呼叫 closesocket() 來將 Socket 關(guān)閉。

◎ WSACancelBlockingCall():取消目前正在進行中的 blocking 動作。

格式: int PASCAL FAR WSACancelBlockingCall( void );

參數(shù): 無

傳回值:成功 – 0

失敗 - SOCKET_ERROR (呼叫 WSAGetLastError() 可得知原因)

說明: 此函式用來取消該應(yīng)用程式正在進行中的 blocking 動作。通常的使用時機有:(a) Blocking 動作正在進行中,該應(yīng)用程式又收到某一訊息(Mouse、Keyboard、Timer 等),則可在處理該訊息的段落中呼叫此函式。(b) Blocking 動作正在進行中,而 Windows Sockets 又呼叫回應(yīng)用程式的「blocking hook」函式時,在該函式內(nèi)可呼叫此函式來取消 blocking 動作。

使用者必須注意,在某一 Winsock blocking 函式動作進行時,除了WSAIsBlocking() 及 WSACancelBlockingCall() 外,不可以再呼叫其它任何Windows Sockets DLL 提供的函式,否則會產(chǎn)生錯誤。另外若取消的blocking 動作不是 accept() 或 select() 的話,那麼該 Socket 可能會處於未定狀態(tài),使用者最好是呼叫 closesocket() 來關(guān)閉該 Socket,而不該再對它做任何動作。

介紹完了 TCP Socket 的資料收送,筆者接著為讀者介紹 sendto() 及recvfrom() 這兩個函式,以及許多人可能很容易搞錯的 FD_WRITE 事件。

sendto及recvfrom

一般言,TCP Socket 使用的是 send() 及 recv() 這兩個函式;而 UDP Socket用的是 sendto() 及 recvfrom() 函式。這是因為 TCP 是 Connection-oriented,必須做完 Socket 真正的連接程序後,才可以開始收送資料,此時系統(tǒng)已經(jīng)知道了連接的對方,所以我們不用再指定資料要送到哪里。而 UDP 是 Connectionless,收送資料的雙方并沒有建立真正的連接,所以我們要利用 sendto() 及 recvfrom()來指定收資料的對方及獲知是誰送資料給我們。TCP Socket 也可以用 sendto() 及 recvfrom() 來送收資料,只是此時這兩個函式的最後兩個參數(shù)沒有作用,會被系統(tǒng)所忽略。而 UDP Socket 如果呼叫了connect() 函式來指定對方的位址(這個 connect 并不會真的和對方做連接的動作,而是告知我們本身的系統(tǒng)說我們只想收、送何方的資料),那麼也可以利用 send() 及 recv() 來送收資料。

sendto():將資料送到使用者指定的目的地。

格 式: int PASCAL FAR sendto( SOCKET s, const char FAR *buf, int len, int flags, const struct sockaddr FAR *to, int tolen );

參數(shù):

s: Socket 的識別碼

buf: 存放要傳送的資料的暫存區(qū)

len: buf 的長度

flags: 此函式被呼叫的方式

to: 資料要送達的位址

tolen: to 的大小

傳回值: 成功 - 送出的資料長度

失敗 - SOCKET_ERROR (呼叫 WSAGetLastError() 可得知原因)

說明: 此函式適用於 Datagram 或 Stream Socket 來傳送資料到指定的位址。 對 Datagram Socket 言,若是 datagram 的大小超過限制,則將不會送出任何資料,并會傳回錯誤值。對 Stream Socket 言,其作用與 send() 相同;參數(shù) to 及 tolen 的值將被系統(tǒng)所忽略。 若是傳送 (transport) 系統(tǒng)內(nèi)之儲存空間不夠存放這些要傳送的資料,sendto() 將會被 block 住,直到資料都被送出;除非該 Socket 被設(shè)定為 non-blocking 模式。使用者亦須注意 sendto()函式執(zhí)行完成,并不表示資料已經(jīng)成功地送抵對方了,而可能仍在系統(tǒng)的 output buffer 中。 flags 的值可設(shè)為 0、MSG_DONTROUTE 及 MSG_OOB 的組合。 (參見 WINSOCK第1.1版51頁)

recvfrom():讀取資料,并儲存資料來源的位址。

格式: int PASCAL FAR recvfrom( SOCKET s, char FAR *buf, int len, int flags, struct socketaddr FAR *from, int FAR *fromlen );

參數(shù):

s: Socket 的識別碼

buf: 存放接收到的資料的暫存區(qū)

len: buf 的長度

flags: 此函式被呼叫的方式

from: 資料來源的位址

fromlen: from 的大小

傳回值: 成功 - 接收到的資料長度 (若對方 Socket 已關(guān)閉,則為 0)

失敗 - SOCKET_ERROR (呼叫 WSAGetLastError() 可得知原因)

說明: 此函式用來讀取資料并記錄資料來源的位址。對 Datagram Socket(UDP)言,一次讀取一個 Datagram;對 Stream Socket (TCP)言,其作用與recv() 相同,參數(shù) from 及 fromlen 的值會被系統(tǒng)忽略。如果 Socket 為 Blocking 模式,且目前 input buffer 內(nèi)沒有任何資料,則 recvftom() 將 block 到有任何資料到達為止;如果為 Non-Blocking 模式,且 input buffer 無任何資料,則會馬上回覆錯誤。

FD_WRITE事件

筆者在前面介紹過 FD_READ 事件的發(fā)生時機,現(xiàn)在繼續(xù)介紹 FD_WRITE這個較易使人混淆的事件,因為真的有相當(dāng)多的人對此一事件的發(fā)生不明了。由字面上看,FD_WRITE 應(yīng)該是要求系統(tǒng)通知我們某個 Socket 現(xiàn)在是否可以呼叫 send 或 sendto 來傳送資料?答案可以說「是」,但是它和 FD_READ卻又有不同的地方。在前面我們知道呼叫一次 recv 後,如果 input buffer 中尚有資料未被取出的話,系統(tǒng)會再通知我們一次 FD_READ。那麼如果我們呼叫一次 send 後,系統(tǒng)的 output buffer 仍有空間可寫入的話,它是否會再通知我們一個FD_WRITE,叫我們繼續(xù)傳送資料呢?這個答案就是「否定」的了!系統(tǒng)并不會再通知我們了。系統(tǒng)會通知我們 FD_WRITE 事件的訊息,只有下列幾種情況:

(1)呼叫 WSAAsyncSelect來設(shè)定 FD_WRITE 事件時,Socket 已經(jīng)可以傳送資料(TCP scoket 已經(jīng)和對方連接成功了,或 UDP socket 已建立完成),且目前 output buffer 仍有空間可寫入資料。

(2)呼叫 WSAAsyncSelect 來設(shè)定 FD_WRITE 事件時,Socket 尚不能傳送資料,不過一旦 Socket 與對方連接成功,馬上就會收到 FD_WRITE 的通知。

(3)呼叫 send 或 sendto 傳送資料時,系統(tǒng)告知錯誤,且錯誤碼為10035 WSAEWOULDBLOCK(呼叫 WSAGetLastError 得知這項錯誤),這時表示 output buffer 已經(jīng)滿了,無法再寫入任何資料(此時即令呼叫再多次的send 也都一定失敗);一旦系統(tǒng)將部份資料成功送抵對方,空出 output buffer後,便會送一個 FD_WRITE 給使用者,告知可繼續(xù)傳送資料了。換句話說,在呼叫 send 傳送資料時,只要不是返回錯誤 10035 的話,便可一直繼續(xù)呼叫 send 來傳送資料;一旦 send 回返錯誤 10035,那麼便不要再呼叫 send傳送資料,而須等收到 FD_WRITE 後,再繼續(xù)傳送資料。

結(jié)語

在這一期的文章中,筆者介紹了各位有關(guān) TCP Socket 的資料收、送方式及FD_READ、FD_WRITE 等事件的發(fā)生時機;讀者們綜合前一期的文章,應(yīng)該已經(jīng)可以建立出一對主從架構(gòu)的程式,并利用 TCP Socket 來傳送資料了。下一期,筆者將繼續(xù)介紹有關(guān)如何獲取網(wǎng)路資訊的函式,如gethostname、getsockname、getpeername,以及同步與非同步的網(wǎng)路資料庫擷取函式 getXbyY、WSAAsyncGetXByY。本文中所提到的 WinKing 試用版可自 SEEDNET 臺北主機 tpts1.seed.net.tw(139.175.1.10)的 UPLOAD/WINKING 目錄中取得,檔名為 wkdemo.exe; WinKing 提供 Ethernet 及 PPP 連線功能,適用於一般 Ethernet 網(wǎng)路,亦可用來以電話、數(shù)據(jù)機連上 SEEDNET 的 PPP 伺服主機;□例 demoserv、democlnt,以及一些筆者所寫的 Winsock 程式(含原始程式碼)則存放在UPLOAD/WINKING/JNLIN 目錄下;有興趣的讀者可自行用 anonymous ftp 方式取得。

獲取網(wǎng)路資訊

在前兩期的文章中,筆者介紹了如何在 Winsock 環(huán)境下建立主從架構(gòu)的TCP Socket,以及如何利用 Socket 來收送資料;今天,我們接著來看一看如何利用 Winsock 所提供的函式來取得一些基本的網(wǎng)路資料,包括我們本身主機的名稱是什麼、系統(tǒng)主動指定給我們的 Socket 的 IP 位址及 port number、我們的 Socket 所連接的對方是誰、如何查得某些主機的 IP 位址或名稱、以及某些well-known 服務(wù)(如 ftp、telnet 等)所用的 port number 是哪一個等等。今天我們使用的展示程式是筆者以前所撰寫的一個針對 Winsock 1.1 的 46 個函式做測試或教學(xué)用的程式,有興趣了解 46 個函式該如何呼叫的讀者,可用anonymous ftp 方式到「tpts1.seed.net.tw」的「UPLOAD/WINKING/JNLIN」目錄下取得此程式的執(zhí)行檔及原始程式碼,檔名為 hello.*。讀者們也可利用hello 程式來模擬 Server 或 Client 程式,以驗證我們所做的動作。

【如何知道我們所使用的 local 主機名稱】

通常我們都會幫我們自己所使用的這臺主機設(shè)定一個名稱;在程式中,我們也可以透過 Winsock 所提供的一個稱為 gethostname() 的函式來取得這一個主機名稱。

◎ gethostname():獲取目前使用者使用的 local host 的名稱。

格 式: int PASCAL FAR gethostname( char FAR *name, int namelen );

參 數(shù): name 用來存放 local host 名稱的暫存區(qū)

namelen name 的大小

傳回值: 成功 – 0

失敗 - SOCKET_ERROR (呼叫 WSAGetLastError() 可得知原因)

說明: 此函式用來獲取 local host 的名稱。在程式中我們呼叫的方法如下:

gethostname( (char FAR *) hname, sizeof(hname) )

讀者們?nèi)绻褂眠^ Trumpet Winsock 的話,可能知道 Trumpet 的環(huán)境設(shè)定中并沒有讓我們設(shè)定 local host 名稱的欄位,所以在執(zhí)行一些 Public Domain 的Winsock 應(yīng)用程式(如 ws_ping、wintalk)時,在呼叫 gethostname() 時會產(chǎn)生錯誤;解決的方法是在 Trumpet 的 「hosts」 檔中加上您的主機 IP 位址及名稱,那麼呼叫這個函式時就不會再產(chǎn)生錯誤了。

【如何得知系統(tǒng)主動指定給我們的 IP 位址及 port number】

以前的文章中,筆者曾提到 Client 端的 TCP Socket 在呼叫 connect() 函式去連接 Server 端之前,可以呼叫 bind() 函式來指定 Client 端 Socket 所用的IP 位址及 port number;但是一般而言,我們 Client 端并不需要呼叫 bind() 來指定特定的 IP 位址及 port number 的,而是交由系統(tǒng)主動幫我們的 Socket 設(shè)定 IP 位址及port number (呼叫 connect() 函式時)。但是我們?nèi)绾蔚弥到y(tǒng)指定了什麼IP位址及 port number 給我們呢?這就要借助 getsockname() 這個函式了。

getsockname():獲取 Socket 的 Local 位址及 port number 資料。

格式: int PASCAL FAR getsockname( SOCKET s, struct sockaddr FAR *name, int FAR *namelen );

參 數(shù): s Socket 的識別碼

name 存放此 Socket 的 Local 位址的暫存區(qū)

namelen name 的長度

傳回值: 成功 – 0

失敗 - SOCKET_ERROR (呼叫 WSAGetLastError() 可得知原因)

說明: 此函式是用來取得已設(shè)定位址或已連接之 Socket 的本端位址資料。若是此 Socket 被設(shè)定為 INADDR_ANY,則需等真正建立連接成功後才會傳回正確的位址。

在程式中呼叫的方法為:

struct sockaddr_in sa;

int salen = sizeof(sa);

getsockname( sd, (struct sockaddr FAR *)&sa, &salen )

【如何知道和我們的 Socket 連接的對方是誰】

連接的 Socket 是有兩端的,所以相對於 getsockname() 函式,Winsock 也提

供了一個 getpeername() 函式,來讓我們獲得與我們連接的對方的 IP 位址與portnumber。

getpeername():獲取連接成功之 Socket 的對方 IP 位址及 port number。

格 式: int PASCAL FAR getpeername( SOCKET s, struct sockaddr FAR *name, int FAR *namelen );

參 數(shù): s Socket 的識別碼

name 儲存與此 Socket 連接的對方 IP 位址的暫存區(qū)

namelen name 的長度

傳回值: 成功 – 0

失敗 - SOCKET_ERROR (呼叫 WSAGetLastError() 可得知原因)

說明: 此函式可用來取得已連接成功的 Socket 的彼端之位址資料。

呼叫的方式如下:

struct sockaddr_in sa;

int salen = sizeof(sa);

getpeername( sd, (struct sockaddr FAR *)&sa, &salen )

現(xiàn)在我們?nèi)匀焕?WinKing 來當(dāng)我們的 Winsock Stack,并利用它所提供的工具來觀察 Sockets 的連結(jié)及資料是否正確。由圖 1,我們可以由 WinKing 的視窗看到我們設(shè)定這臺主機的名稱是「vincent」,IP 位址是 「140.92.61.24」。我們并利用兩個 hello 程式,一個當(dāng)成 Client (畫面右邊打開者),一個當(dāng)成 Server (畫面左邊最小化者)。Server所用的 port number 是 「7016」; Client 并沒有呼叫 bind() 來指定 port number,而是呼叫 connect() 時由系統(tǒng)指定。我們呼叫 gethostname(),得到的答案是 「vincent」;而 Client 呼叫g(shù)etsockname() 得到自己的 IP 位址是 「140.92.61.24」,port number 是 「2110」(筆者以前曾提過,由系統(tǒng)主動指定的 port number 會介於 1024 到 5000 間);再呼叫 getpeername() 得到與 Client 連接的 Server 端 IP 位址是 「140.92.61.24」(因為我們的 Client 和 Server 都在同一臺主機),port number 是 「7016」。果然沒錯!(由 WinKing 的 Sockets' Status 視窗亦可觀察到相互連接的 Sockets 資料,與我們呼叫函式所得結(jié)果相同)

讀者必須注意一點,getsockname() 及 getpeername() 所取得的 IP 位址及 port number 都是 network byte order,而不是 host byte order;如果您想轉(zhuǎn)成 host byte order,就必須借助 ntohl() 及 ntohs() 兩個函式。而我們能看到 IP 位址以「字串」方式表達出來,則又是利用了 inet_ntoa() 函式;相對地,我們也可利用inet_addr() 函式將字串方式的 IP 位址轉(zhuǎn)換成 in_addr 格式(network byte order 的unsigned long)。

inet_ntoa():將一網(wǎng)路位址轉(zhuǎn)換成「點格式」字串。

格 式: char FAR * PASCAL FAR inet_ntoa( struct in_addr in );

參 數(shù): in 一個代表 Internet host 位址的結(jié)構(gòu)

傳回值: 成功 - 一個代表位址的「點格式」(dotted) 字串

失敗 – NULL

說明: 此函式將一 Internet 位址轉(zhuǎn)換成「a.b.c.d」字串格式。

struct sockaddr {

u_short sa_family; /* address family */

char sa_data[14]; /* up to 14 bytes of direct address */

};

struct in_addr {

union {

struct { u_char s_b1,s_b2,s_b3,s_b4; } S_un_b;

struct { u_short s_w1,s_w2; } S_un_w;

u_long S_addr;

} S_un;

#define s_addr S_un.S_addr /* can be used for most tcp & ip code */

#define s_host S_un.S_un_b.s_b2 /* host on imp */

#define s_net S_un.S_un_b.s_b1 /* network */

#define s_imp S_un.S_un_w.s_w2 /* imp */

#define s_impno S_un.S_un_b.s_b4 /* imp # */

#define s_lh S_un.S_un_b.s_b3 /* logical host */

};

struct sockaddr_in {

short sin_family;

u_short sin_port;

struct in_addr sin_addr;

char sin_zero[8];

};

inet_addr():將字串格式的位址轉(zhuǎn)換成 32 位元 in_addr 的格式。

格 式: unsigned long PASCAL FAR inet_addr( const char FAR *cp );
參 數(shù): cp 一個代表 IP 位址的「點格式」(dotted) 字串
傳回值: 成功 - 一個代表 Internet 位址的 unsigned long
失敗 - INADDR_NONE
說明: 此函式將一「點格式」的位址字串轉(zhuǎn)換成適用之 Intenet 位址。
「點格式」字串可為以下四種方式之任一:
(i) a.b.c.d (ii) a.b.c (iii) a.b (iv) a

圖 1 的 hello 程式中,我們將 Local 資料寫到 dispmsg 中,再顯示出來;其

用法如下:

wsprintf((LPSTR)dispmsg, "OK! local ip=%s, local port=%d",
inet_ntoa(sa.sin_addr), ntohs(sa.sin_port));

【W(wǎng)insock 提供的資料庫函式】

Winsock 也提供了同步與非同步的網(wǎng)路資料庫函式;不過讀者們要知道,此處的資料庫指的并非如 Informix, Oracle 等商業(yè)用途的資料庫系統(tǒng),而是指主機IP 位址及名稱、well-known 服務(wù)的名稱及 Socket 型態(tài)及所用的 port number、以及協(xié)定(protocol)名稱及代碼等。

【同步資料庫函式】

首先我們來看一下第一組:gethostbyname() 及 gethostbyaddr() 函式這兩個函式的用途是讓我們可以由某個主機名稱求得它的 IP 位址,或是由它的 IP 位址求得它的名稱。一般我們經(jīng)常會用到的是由名稱求得 IP 位址;因為很少人會去記某臺機器的 IP 位址的,另外 TCP/IP 封包的 IP header 上也必須記載送、收主機的 IP 位址,而不是主機名稱。

gethostbyname():利用某一 host 的名稱來獲取該 host 的資料。

格 式: struct hostent FAR * PASCAL FAR gethostbyname( const char FAR *name );

參 數(shù): name host 的名稱

傳回值: 成功 - 指向一個 hostent 結(jié)構(gòu)的指標(biāo)

失敗 - NULL (呼叫 WSAGetLastError() 可得知原因)

說明: 此函式是利用 host 名稱來獲取該主機的其他資料,如 host 的位址、別名,位址的型態(tài)、長度等。

gethostbyaddr():利用某一 host 的 IP 位址來獲取該 host 的資料。

格 式: struct hostent FAR * PASCAL FAR gethostbyaddr( const char FAR *addr, int len, int type );

參 數(shù): addr network 排列方式的位址

len addr 的長度

type PF_INET(AF_INET)

傳回值: 成功 - 指向一個 hostent 結(jié)構(gòu)的指標(biāo)

失敗 - NULL (呼叫 WSAGetLastError() 可得知原因)

說明: 此函式是利用 IP 位址來獲取該主機的其他資料,如 host 的名稱、別名,位址的型態(tài)、長度等。

程式中呼叫的方式分別如下:

char host_name[30];

struct hostent far *htptr;

/* 假設(shè) host_name 的值已先設(shè)定為我們要求得資料的主機名稱 */

htptr = (struct hostent FAR *) gethostbyname( (char far *) host_name )

struct in_addr host_addr;

struct hostent far *htptr;

/* 假設(shè) host_addr 的值已先設(shè)定為我們要求得資料的主機的network byte order 方式的 IP 位址*/

htptr = (struct hostent FAR *) gethostbyaddr((char far *)&host_addr, 4, PF_INET)

一般言,程式中呼叫到 gethostbyname() 及 gethostbyaddr() 時,Winsock Stack 會先在 local 的 「hosts」檔中找看看是否有這個主機的資料;如果沒有, 則可能再透過「領(lǐng)域名稱服務(wù)」(Domain Name Service)的功能,向「名稱伺服器」(Name Server)查詢;所以呼叫這兩個函式時,有時會等一下子才獲得答覆。如果您想讓程式執(zhí)行快一些的話,可將常用主機的資料放在 hosts 檔中,這樣就不必透過 DNS 去查詢了。

接下來我們來看 getservbyname() 及 getservbyport() 這兩個函式。大部份的讀者應(yīng)該都用過 telnet、mail、ftp、news 等服務(wù)應(yīng)用程式;這些應(yīng)用程式的協(xié)定,比如服務(wù)名稱、伺服器端所用的 port number、以及 Socket 的型態(tài),都是固定的;這些資料,我們就可以利用 getservbyname() 或 getservbyport()來取得,而不必刻意去記頌它們。

◎ getservbyname():依照服務(wù) (service) 名稱及通訊協(xié)定(tcp/udp)來獲取該服務(wù)的其他資料。

格 式: struct servent * PASCAL FAR getservbyname( const char FAR *name, const char FAR *proto );

參 數(shù): name 服務(wù)名稱

proto 通訊協(xié)定名稱

傳回值: 成功 - 一指向 servent 結(jié)構(gòu)的指標(biāo)

失敗 - NULL (呼叫 WSAGetLastError() 可得知原因)

說明: 利用服務(wù)名稱及通訊協(xié)定來獲得該服務(wù)的別名、使用的 port 號碼等。

◎ getservbyport():依照服務(wù) (service) 的 port 號碼及通訊協(xié)定(tcp/udp)來獲取該服務(wù)的其他資料。

格 式: struct servent * PASCAL FAR getservbyport( int port, const char FAR *proto );

參 數(shù): port 服務(wù)的 port 編號

proto 通訊協(xié)定名稱

傳回值: 成功 - 一指向 servent 結(jié)構(gòu)的指標(biāo)

失敗 - NULL (呼叫 WSAGetLastError() 可得知原因)

說明: 利用 port 編號及通訊協(xié)定來獲得該服務(wù)的名稱、別名等。

程式中的使用方法分別為:

char serv_name[20];
char proto[10];
struct servent far *svptr;
/* 假設(shè) serv_name 及 proto 已先設(shè)好服務(wù)名稱及通訊協(xié)定 */
svptr = (struct servent FAR *)getservbyname( (char far *)serv_name, (char far*)proto )

int serv_port;
char proto[10];
struct servent far *svptr;
/* 假設(shè) serv_port 及 proto 已先設(shè)好服務(wù)所用的 port number 及通訊協(xié)定 */

svptr = (struct servent FAR *)getservbyport( htons(serv_port), (char far*)proto) )

Winsock 環(huán)境下,我們能夠查詢到的服務(wù)資料都是存放在 local 的「services」檔中;這個檔所存放的都是 well-known 的服務(wù),基本上我們是不需去更改它的。讀者也可以將自己提供的服務(wù)加到這個檔中,不過您所用的服務(wù)資料要公諸於世,不然別人的 services 檔中可是沒有您的服務(wù)的資料喲。

最後的這組 getprotobyname() 及 getprotobynumber() 函式是用來取得一些「協(xié)定」的資料,比如 tcp、udp、igmp 等。一般而言,我們是不太會用到的。

◎ getprotobyname():依照通訊協(xié)定 (protocol) 的名稱來獲取該通訊協(xié)定的其他資料。

格 式: struct protoent FAR * PASCAL FAR getprotobyname( const char FAR *name );

參 數(shù): name 通訊協(xié)定名稱

傳回值: 成功 - 一指向 protoent 結(jié)構(gòu)的指標(biāo)

失敗 - NULL (呼叫 WSAGetLastError() 可得知原因)

說明: 利用通訊協(xié)定的名稱來得知該通訊協(xié)定的別名、編號等資料。

◎ getprotobynumber():依照通訊協(xié)定的編號來獲取該通訊協(xié)定的其他資料。

格 式: struct protoent FAR * PASCAL FAR
getprotobynumber( int number );
參 數(shù): number 以 host order 排列方式的通訊協(xié)定編號
傳回值: 成功 - 一指向 protoent 結(jié)構(gòu)的指標(biāo)
失敗 - NULL (呼叫 WSAGetLastError() 可得知原因)
說明: 利用通訊協(xié)定的編號來得知該通訊協(xié)定的名稱、別名等資料。

程式中呼叫方式分別如下:

struct protoent far *ptptr;
char proto_name[20];
/* 假設(shè) proto_name 已先設(shè)好協(xié)定名稱 */

ptptr = (struct protoent FAR *)getprotobyname( (char far *)proto_name)

struct protoent far *ptptr;
int proto_num;
/* 假設(shè) proto_num 已先設(shè)好協(xié)定編號 */
ptptr = (struct protoent FAR *)getprotobynumber( proto_num )

Winsock Stack 對於應(yīng)用程式呼叫 getprotobyname() 及 getprotobynumber()的資料,是取自於 local 的「protocol」檔;如無需要,我們也不用去變更這個檔案的內(nèi)容。

(圖 2)hello 程式呼叫同步資料庫函式

【非同步資料庫函式】

Winsock 1.1 針對前面筆者所描述的 6 個同步資料庫函式,也提供了相對的6 個非同步資料庫函式,它們分別是 WSAAsyncGetHostByName()、WSAAsyncGetHostByAddr()、WSAAsyncGetServByName()、WSAAsyncGetServByPort()、WSAAsyncGetProtoByName()、WSAAsyncGetProtoByNumber()。

由於它們?nèi)〉玫馁Y料與同步資料庫函式相同,所以筆者僅以WSAAsyncGetHostByName() 為例,說明這些非同步函式,并告訴各位讀者,同步和非同步資料庫函式不同的地方。

由字面來看,「非同步」的意思就是我們發(fā)出問題時,并不會馬上得到答覆,而等到系統(tǒng)取到資料時再告知我們。沒錯,這些非同步資料庫函式的作用就是這樣。和 WSAAsyncSelect() 函式一樣,我們要告訴 Winsock 系統(tǒng)一個接受通知訊息的視窗及訊息代碼,以便系統(tǒng)通知我們。

我們呼叫同步資料庫函式時,return 值 是一個指到相對資料的暫存區(qū),而這個資料暫存區(qū)是由系統(tǒng)所提供的;但是呼叫非同步資料庫函式時,我們必須自己準(zhǔn)備資料暫存區(qū),并將此暫存區(qū)的位址當(dāng)成參 數(shù),傳給系統(tǒng),以便系統(tǒng)用來儲存取到的資料。讀者們必須特別注意一點:在系統(tǒng)通知資料取得成功或失敗前,千萬不可將傳給系統(tǒng)的資料暫存區(qū)刪除釋放,不然當(dāng) 系統(tǒng)取得資料要寫入時,資料區(qū)已不見了,會導(dǎo)至當(dāng)機的。除此之外,資料暫存區(qū)的大小一定要夠大,才足夠讓系統(tǒng)用來存放取得的資料。(Winsock 規(guī)格中的建議值是MAXGETHOSTSTRUCT 1024 bytes 大小的暫存區(qū),筆者認為太大了,100 byets差不多就太夠了)

呼叫非同步資料庫函式時,得到的 return 值是一個代碼,此代碼代表的就是此項呼叫在系統(tǒng)內(nèi)的編號;由於是非同步,所以我們在得到答案前,仍可呼叫 WSACancelAsyncRequest() 函式來取消原先的呼叫,這個取消的動作就要利用到該代碼了。另外,當(dāng)我們收到結(jié)果通知時,wParam 的值也是這個代碼;我們此時可以利用 WSAGETASYNCERROR(lParam) 來得知資料取得是成功或失敗;如果失敗的原因是原先傳入的暫存區(qū)太小的話,我們亦可利用WSAASYNCGETBUFLEN(lParam) 來得知至少要多大的暫存區(qū)才夠。

◎ WSAAsyncGetHostByName():利用某一 host 的名稱來獲取該 host 的資料。(非同步方式)

格 式: HANDLE PASCAL FAR WSAAsyncGetHostByName( HWND hWnd,
unsigned int wMsg, const char FAR *name, char FAR *buf, int buflen );

參 數(shù): hWnd 動作完成後,接受訊息的視窗 handle
wMsg 傳回視窗的訊息
name host 名稱
buf 存放 hostent 資料的暫存區(qū)
buflen buf 的大小
傳回值: 成功 - 代表此非同步動作的 handle 代碼
失敗 - 0 (呼叫 WSAGetLastError() 可得知原因)
說明: 此函式是利用 host 名稱來獲取其他的資料,如 host 的位址、別名,位址的型態(tài)、長度等。使用者呼叫此函式時必須傳入要接收資料的視窗 handle、訊息代碼、資料的存放位址指標(biāo)等,以便得到資料時可以通知該視窗來使用資料。呼叫此函式後會馬上回到使用者的呼叫點并傳回一個 handle 代碼,此代碼可用來辨別此非同步動作或用來取消此非同步動作。當(dāng)資料取得後,系統(tǒng)會送一個訊息到使用者指定的視窗。

◎ WSACancelAsyncRequest():取消某一未完成的非同步要求。

格 式: int PASCAL FAR WSACancelAsyncRequest( HANDLEhAsyncTaskHandle );

參 數(shù):hAsyncTaskHandle 要取消的 task handle 代碼
傳回值: 成功 - 0
失敗 - SOCKET_ERROR (呼叫 WSAGetLastError() 可得知原因)
說明: 此函式是用來取消原先呼叫但尚未完成的WSAAsyncGetXByY(),例如 WSAAsyncGetHostByName(),的動作。參數(shù) hAsyncTaskHandle 即為呼叫WSAAsyncGetXByY() 時傳回之代碼值。若是原先呼叫之非同步要求已經(jīng)完成,則無法加以取消。

(圖 3)hello 程式呼叫非同步資料庫函式

【結(jié)語】

筆者已經(jīng)為各位介紹了大部份 Winsock 應(yīng)用程式設(shè)計時會用到的函式,不知讀者中是否已有人開始練習(xí)自己寫 Winsock 網(wǎng)路程式了嗎?下一期,筆者會將剩下的函式都介紹完。再此筆者并期待各位除了使用別人設(shè)計的網(wǎng)路軟體外,大家也都能自己練習(xí)設(shè)計出一些不錯的網(wǎng)路應(yīng)用軟體,讓世界其他國家的人知道臺灣也有能人的;愿共勉之。

其它

接著筆者要再為各位介紹剩下的幾個函式,包括 select()、setsockopt()、getsockopt(),以及變更系統(tǒng)的 Blocking Hook 函式時,所要用到的WSASetBlockingHook() 和 WSAUnhookBlockingHook()。

select【查詢讀寫連接中斷狀態(tài)】

如果寫過 UNIX BSD socket 程式的讀者,一定都知道這個select()函式是很好用的。因為它可以幫您檢查一整組(set)的 sockets 是否可以讀、寫資料,也可以用來檢查 socket 是否已和對方連接成功,或者是對方是否已將相對的socket 關(guān)閉等。但是在 Winsock 1.1 及 MS Windows 3.X 「非強制性多工」的環(huán)境下,它是否仍是那麼好用呢?我們在使用它時,是否要注意些什麼呢?

◎ select():檢查一或多個 Sockets 是否處於可讀、可寫或錯誤的狀態(tài)。

格式:

int PASCAL FAR select( int nfds, fd_set FAR *readfds, fd_set FAR *writefds, fd_set FAR *exceptfds,

const struct time val FAR *timeout )

參數(shù):

nfds: 此參數(shù)在此并無作用

readfds: 要被檢查是否可讀的 Sockets

writefds: 要被檢查是否可寫的 Sockets

exceptfds:要被檢查是否有錯誤的 Sockets

timeout: 此函式該等待的時間

傳回值: 成功 - 符合條件的 Sockets 總數(shù) (若 Timeout 發(fā)生,則為0)

失敗 - SOCKET_ERROR (呼叫 WSAGetLastError() 可得知原因)

說明:使用者可利用此函式來檢查 Sockets 是否有資料可被讀取,或是有空間可以寫入,或是有錯誤發(fā)生。Winsock 1.1 所提供的 select() 函式與 UNIX BSD 的 select() 函式,在參數(shù)的個數(shù)及資料型態(tài)上是一樣,都有 nfds、readfds、writefds、exceptfds、及 timeout五個參數(shù);但是 Winsock 的 nfds 是沒有作用的,有這個參數(shù)的目的只是為了與 UNIX BSD 的 select() 函式一致。至於 readfds、writefds、exceptfds 同樣是一組 sockets 的集合,所以您可以同時設(shè)定許多 sockets 的號碼在這三個參數(shù)里面;當(dāng)然這些 sockets 必須是屬於您的這個應(yīng)用程式所建立的。如果您設(shè)定的 socket 號碼中有任一個不是屬於您的這個程式的話,呼叫 select() 函式便會失敗(錯誤碼為 10038 WSAENOTSOCK)。

Winsock 同樣也提供了一些 macros 來讓您設(shè)定或檢查 readfds、writefds、exceptfds 的值,包括有:

2 FD_ZERO(*set) -- 將 set 的值清乾凈

2 FD_SET(s, *set) -- 將 s 加到 set 中

2 FD_CLR(s, *set) -- 將 s 從 set 中刪除

2 FD_ISSET(s, *set) -- 檢查 s 是否存在於 set 中

其中 s 代表的是某一個 socket 的號碼,set 代表的就是 readfds、writefds 或 exceptfds。

讀者們要知道參數(shù)readfds、writefds及exceptfds 都是「called by value- result」。

「called by value-result」的意思就是說,我們在將參數(shù)傳給系統(tǒng)時,要先設(shè)啟始值,并將這些參數(shù)的位址(address)告訴系統(tǒng);而系統(tǒng)則會利用到這些值來做些運算或其他用途,最後并將結(jié)果再寫回這些參數(shù)的位址中。因此這些參數(shù)的值在傳入前和函式回返後可能會不同,所以每次呼叫select() 前對這些參數(shù)一定要重新設(shè)定它們的值。

假設(shè)我們要檢查 socket 1 和 2 目前是否可以用來傳送資料,以及 socket 3 是否有資料可讀,我們不打算檢查 sockets 是否有錯誤發(fā)生,所以 exceptfds 設(shè)為NULL。步驟大致如下:

FD_ZERO( &writefds ); //清除 writefds

FD_ZERO( &readfds ); //清除 readfds

FD_SET( 1, &writefds ); //將 socket 1 加到 writefds

FD_SET( 2, &writefds ); //將 socket 2 加到 writefds

FD_SET( 3, &readfds ); //將 socket 3 加到 readfds

select( ..., &readfds, &writefds, NULL, ...) /* 呼叫 select() 來檢查事件 */

if(FD_ISSET( 1, &writefds )) //檢查 socket 1 是否可寫

send( 1, data ); //呼叫 send() 一定成功

if (FD_ISSET( 2, &writefds )) //檢查 socket 2 是否可寫

send( 2, data ); //呼叫 send() 一定成功

if (FD_ISSET( 3, &readfds )) //檢查 socket 2 是否可讀

recv( 3, data ); //呼叫 recv() 一定成功

select() 函式的第五個參數(shù)「timeout」,是讓我們用來設(shè)定 select 函式要等待(block)多久。茲述說如下:

(1)如果 timeout 設(shè)為「NULL」,那麼 select() 就會一直等到「至少」某一個 socket 的事件成立了才會 return,這和其他的 blocking 函式一樣。

select( ..., NULL ) /* blocking */

(2)如果 timeout 的值設(shè)為 {0, 0} (秒, 微秒),那麼 select() 在檢查後,不管有沒有 socket 的事件成立,都會馬上 return,而不會停留。

timeout.tv_sec = timeout.tv_usec = 0;

select( ..., &timeout ) /* non-blocking */

(3)如果 timout 設(shè)為 {m, n},那麼就會等到至少某一個 socket 的事件發(fā)生,或是時間到了(m 秒 n 微秒),才會 return。

timeout.tv_sec = m;

timeout.tv_usec = n;

select( ..., &timeout ) /* wait m secconds n microseconds */

在 UNIX 系統(tǒng)上,我們通常會利用select()來做「polling」的動作,檢查事件是否發(fā)生;但是在 MS Windows 3.X 的環(huán)境下一直做 polling 的動作一定要非常小心,不然可能會造成整個 Windows 系統(tǒng)停住(因為 CPU 都被您的程式占用了);所以使用時一定要注意「控制權(quán)釋放」,不然就是「不要將 timeout 設(shè)為 {0,0}」(因為 timeout 設(shè)為 {0,0} 的話, Winsock 系統(tǒng)內(nèi)部可能不會呼叫到Blocking Hook 函式來釋放控制權(quán))。UNIX 系統(tǒng)由於是「Time Sharing」的方式,所以并不會有類似的問題。(所謂 polling 的動作是指在程式中有一個回圈,而在回圈內(nèi)一直呼叫像select這樣的函式做檢查的動作

select()除了可以用來檢查socket是否可讀寫外,對於non-blocking的socket在呼叫connect()後,也可利用select()的 writefds 來檢查連接是否已經(jīng)成功了(當(dāng)這個non-blocking的socket被設(shè)定在 writefds,且被 select 成功時);此外,我們亦可利用readfds來檢查 TCP socket 連接的對方是否已經(jīng)關(guān)閉了(當(dāng)此socket被設(shè)定在readfds,且被select成功,但呼叫recv去收資料卻 return 0 時)。

UNIX 系統(tǒng)上因為沒有提供 WSAAsyncSelect() 函式,所以我們要用 select()函式來做 polling 的動作;但是 Winsock 系統(tǒng)上已經(jīng)有了可以設(shè)定非同步事件的WSAAsyncSelect() 函式,為了讓 MS Windows「訊息驅(qū)動」(message driven)的環(huán)境更有效率,讀者們應(yīng)該盡量使用 WSAAsyncSelect(),而少用 select() 的方式;這也是當(dāng)初為什麼要定義一個 WSAAsyncSelect() 函式的最大目的。

setsockopt【變更socket options】

Winsock 1.1 也提供了一個變更 socket options 的 setsockopt() 函式;由於options 的項目很多,筆者僅就數(shù)個較會用到的項目來解說,其馀的項目請讀者們自行研究。

◎ setsockopt():設(shè)定 Socket 的 options。

格式:

int PASCAL FAR setsockopt( SOCKET s, int level, int optname, const char FAR *optval, int optlen )

參數(shù):

s: Socket 的識別碼

level: option 設(shè)定的 level (SOL_SOCKET 或 IPPROTO_TCP)

optname: option 名稱

optval: option 的設(shè)定值

optlen: option 設(shè)定值的長度

傳回值:

成功 – 0

失敗 - SOCKET_ERROR (呼叫 WSAGetLastError() 可得知原因)

說明: 此函式用來設(shè)定 Socket 的一些 options,藉以更改其動作。可更改的options 有:(詳見 Winsock Spec. 54 頁)

Option Type

SO_BROADCAST BOOL

SO_DEBUG BOOL

SO_DONTLINGER BOOL

SO_DONTROUTE BOOL

SO_KEEPALIVE BOOL

SO_LINGER struct linger FAR*

SO_OOBINLINE BOOL

SO_RCVBUF int

SO_REUSEADDR BOOL

SO_SNDBUF int

TCP_NODELAY BOOL

(1)SO_BROADCAST -- 適用於 UDP socket。其意義是允許UDP socket「廣播」broadcast訊息到網(wǎng)路上。

(2)SO_DONTLINGER -- 適用於 TCP socket。其意義是讓 socket 在呼叫 closesocket() 關(guān)閉時,能馬上 return,而不用等到資料都送完後才從函式呼叫return;closesocket() 函式 return 後,系統(tǒng)仍會繼續(xù)將資料全部送完後,才真正地將這個 socket 關(guān)閉。一個 TCP socket 在開啟時的預(yù)設(shè)值即是 Don't Linger。

(3)SO_LINGER -- 適用於 TCP socket 來設(shè)定 linger 值之用。如果 linger的 值設(shè)為 0,那麼在呼叫 closesocket() 關(guān)閉 socket 時,如果該 socket 的 output buffer 中還有資料的話,將會被系統(tǒng)所忽略,而不會被送出,此時 closesocket() 也會馬上 return;如果 linger 值設(shè)為 n 秒,那麼系統(tǒng)就會在這個時間內(nèi),嘗試去送出output buffer 中的資料,時間到了或是資料送完了,才會從 closesocket() 呼叫return。

(4)SO_REUSEADDR -- 允許 socket 呼叫 bind() 去設(shè)定一個已經(jīng)用過的位址(含 port number)。

我們就以設(shè)定某個socket的 linger 值為例,看看程式中該如何呼叫 setsockopt() 這個函式:

struct linger Linger;

Linger.l_onoff = 1; //開啟 linger 設(shè)定

Linger.l_linger = n; //設(shè)定 linger 時間為 n 秒

setsockopt( s, SOL_SOCKET, SO_LINGER, &Linger, sizeof(struct linger) )

相對地,如果我們想要知道目前的某個 option 的設(shè)定值,那麼就可以利用getsockopt() 函式來取得。

getsockopt【獲取socket options】

◎ getsockopt():取得某一 Socket 目前某個 option 的設(shè)定值。

格式:

int PASCAL FAR getsockopt( SOCKET s, int level, int optname, char FAR *optval, int FAR *optlen )

參數(shù):

S: Socket 的識別碼

Level: option 設(shè)定的 level

optname: option 名稱

optval: option 的設(shè)定值

Optlen: option 設(shè)定值的長度

傳回值:

成功 – 0

失敗 - SOCKET_ERROR (呼叫 WSAGetLastError() 可得知原因)

說明: 此函式用來獲取目前 Socket的某些 options 設(shè)定值。同樣地,我們?nèi)砸匀〉媚硞€ socket 的 linger 值為例,看一下程式中應(yīng)該如何呼叫 getsockopt():

struct linger Linger;

int opt_len = sizeof(struct linger);

getsockopt( s, SOL_SOCKET, SO_LINGER, &Linger, &opt_len)

WSASetBlockingHook

【什麼是 Blocking Hook 函式及如何設(shè)定自己的 Blocking Hook 函式】

什麼是「Blocking Hook」函式呢?在解釋之前,我們要先來剖析一下Winsock 1.1 提供的 Blocking 函式(如 accept、connect 等)的內(nèi)部究竟做了哪些事?在 Winsock Stack 的 Blocking 函式內(nèi)部,除了會檢查一些條件外(比如該應(yīng)用程式是否已呼叫過 WSAStartup()?傳入的參數(shù)是否正確?等等),便會進入一個類似下面的回圈:

for (;;)

{

/* 執(zhí)行 Blocking Hook 函式 */

while (BlockingHook());

/* 檢查使用者是否已經(jīng)呼叫了 WSACancelBlockingCall() */

if (operation_cancelled()) break;

/* 檢查動作是否完成了? */

if (operation_complete()) break;

}

現(xiàn)在我們可以很清楚地知道 Blocking 函式的回圈中,有三件重要的事:

(1)執(zhí)行 Blocking Hook 函式

(2)檢查使用者是否呼叫了 WSACancelBlockingCall()來取消此 Blocking 函式的呼叫?

(3)檢查此 Blocking 函式的動作是否已經(jīng)完成了?

讀者們必須注意,不同的 Winsock Stack 在執(zhí)行這三件事時的順序可能會不相同;有的 Winsock Stack 可能會先檢查 Blocking 函式的動作是否已經(jīng)完成了,然後再執(zhí)行 Blocking Hook 函式;所以 Blocking Hook 函式有可能不會被呼叫到。待會解釋完 Blocking Hook 函式的重點後,讀者們就可以知道筆者為什麼在前面告訴各位在使用 polling 方式時一定要非常小心了。

由上面的回圈,我們現(xiàn)在可以知道 Blocking Hook 函式的使用時機是讓系統(tǒng)在等待 Blocking 函式完成前所呼叫的,它并不是給我們自己的應(yīng)用程式所使用的。Winsock 系統(tǒng)本身內(nèi)部就有一個預(yù)設(shè)的 Blocking Hook 函式;現(xiàn)在我們就來看一下這個預(yù)設(shè)的 Blocking Hook 函式會做些什麼事?

BOOL DefaultBlockingHook(void)

{

MSG msg;

BOOL ret;

/* 取得下一個訊息;如果有,就處理它;如果沒有,就釋出控制權(quán) */

ret = (BOOL) PeekMessage(&msg, NULL, 0, 0, PM_REMOVE);

if (ret) {

TranslateMessage(&msg);

DispatchMessage(&msg);

}

return ret;

}

Blocking Hook 函式中很重要的地方就是:讓 Blocking 函式在等待動作完成前能夠處理其他訊息,或是釋出 CPU 控制權(quán),以便讓其他的應(yīng)用程式也有執(zhí)行的機會。

現(xiàn)在回到前面一點的地方,大家仔細想一想:如果在一個 Winsock Stack 的Blocking 函式的回圈內(nèi),先檢查 Blocking 函式的動作是否已經(jīng)完成了,然後再執(zhí)行 Blocking Hook 函式的話;那麼是否就有可能不會釋出 CPU 控制權(quán)來讓其他的程式有執(zhí)行的機會呢?如果我們的程式中再有類似下面的一個回圈,那麼整個Windows 環(huán)境可能就會因我們的程式而 hang 住了。

for (;;)

{

FD_ZERO(&writefds);

FD_SET( s, &writefds );

timeout.tv_sec = timeout.tv_usec = 0;

n = select( 64, NULL, &writefds, NULL, &timeout );

if ( n > 0 ) break;

if ( n == 0) continue;/* timeout */

...

}

send( s, data ... );

在這個回圈例子中,我們原是希望利用 select() 及 polling 的方式來檢查 socket 的 output buffer 中是否尚有空間可寫入資料?如果此時 output buffer 恰好滿了, select() 函式中一檢查到如此的情況,且 timeout 又是 {0,0},那麼就會馬上return 0,而不會呼叫到 Blocking Hook 函式來釋放 CPU 控制權(quán)給 Windows 環(huán)境中的其他程式(包括 Winsock 收送的 Protocol Stack );由於沒有分配到 CPU 時間,所以 Winsock Kernel 便無法將 output buffer 中任何資料送出; Windows 系統(tǒng)因此就 hang 住了 !

Blocking Hook 函式中除了 CPU 控制權(quán)釋放的問題外,還需注意什麼呢?大家再看一看前面 Blocking 函式的回圈;回圈內(nèi)呼叫 Blocking Hook 函式是包在另一個無窮的 while 回圈內(nèi)。如果一個 Blocking Hook 函式的 return 值永遠不為 0 的話,那麼也就永遠被困在這個無窮回圈內(nèi)了;所以我們在設(shè)計自己的 Blocking Hook 函式時一定也要非常小心這個 return 值。

知道了 Blocking Hook 函式的用途及設(shè)計 Blocking Hook 函式該注意的地方後,我們究竟要如何取代掉系統(tǒng)原有的 Blocking Hook 函式呢?那就要利用WSASetBlockingHook() 函式了。

WSASetBlockingHook():建立應(yīng)用程式指定的 blocking hook 函式。

格式: FARPROC PASCAL FAR WSASetBlockingHook( FARPROC lpBlockFunc )

參數(shù): lpBlockfunc 指向要裝設(shè)的 blocking hook 函式的位址的指標(biāo)

傳回值:指向前一個 blocking hook 函式的位址的指標(biāo)

說明: 此函式讓使用者可以設(shè)定他自己的 Blocking Hook 函式,以取代原先系統(tǒng)預(yù)設(shè)的函式。被設(shè)定的函式將會在應(yīng)用程式呼叫到「blocking」動作時執(zhí)行。唯一可在使用者指定的 blocking hook 函式中呼叫的 Winsock 介面函式只有WSACancelBlockingCall()。假設(shè)我們自己設(shè)計了一個 Blocking Hook 函式叫 myblockinghook,那麼在程式中向 Winsock 系統(tǒng)注冊的方法如下:(其中_hInst代表此task的 Instance)

FARPROC lpmybkhook = NULL;

lpmybkhook = MakeProcInstance( (FARPROC)myblockinghook, _hInst) );

WSASetBlockingHook( (FARPROC)lpmybkhook );

我們在設(shè)定自己的 Blocking Hook 程式後,仍可以利用WSAUnhookBlockingHook() 函式,來取消我們設(shè)定的 Blocking Hook 函式,而變更回原先系統(tǒng)內(nèi)定的 Blocking Hook 函式。

WSAUnhookBlockingHook():復(fù)原系統(tǒng)預(yù)設(shè)的 blocking hook 函式。

格 式: int PASCAL FAR WSAUnhookBlockingHook( void )

參 數(shù): 無

傳回值: 成功 – 0

失敗 - SOCKET_ERROR (呼叫 WSAGetLastError() 可得知原因)

說明: 此函式取消使用者設(shè)定的 blocking hook 函式,而回復(fù)系統(tǒng)原先預(yù)設(shè)的 blocking hook 函式。

最後筆者要再說明一點,一個應(yīng)用程式所設(shè)定的 Blocking Hook 函式,只會被這個應(yīng)用程式所使用;其他的應(yīng)用程式并不會執(zhí)行到您設(shè)定的 Blocking Hook 函式的。另外若非極有必要,最好是不要任意變更系統(tǒng)的 Blocking Hook 函式;因為一旦您沒有設(shè)計好的話,整個 Windows 環(huán)境可能就完蛋了。

【結(jié)語】

四期的「Winsock 應(yīng)用程式設(shè)計篇」在此結(jié)束了;筆者除了介紹 Winsock API 外,也將自己親身設(shè)計 winsock.dll 的經(jīng)驗與各位讀者分享了;希望這幾期的文章,對於國內(nèi)想要在 Winsock 1.1 環(huán)境上開發(fā)網(wǎng)路應(yīng)用程式的讀者有些許的幫助。謝謝大家。

[Microsoft Windows-specific Extensions]

(1) WSAAsyncGetHostByAddr():利用某一 host 的位址來獲取該 host 的資料。(非同步方式)

格 式: HANDLE PASCAL FAR WSAAsyncGetHostByAddr( HWND hWnd, unsigned int wMsg, const char FAR *addr, int len, int type, char FAR *buf, int buflen );

參 數(shù):

hWnd 動作完成後,接受訊息的視窗 handle

wMsg 傳回視窗的訊息

addr network 排列方式的位址

len addr 的長度

type PF_INET(AF_INET)

buf 存放 hostent 資料的區(qū)域

buflen buf 的大小

傳回值: 成功 - 代表此 Async 動作的 handle

失敗 - 0 (呼叫 WSAGetLastError() 可得知原因)

說明: 此函式是利用位址來獲取 host 的其他資料,如 host 的名稱、別名, 位址的型態(tài)、長度等。使用者呼叫此函式時必須傳入要接收資料的視窗handle、訊息代碼、資料的存放位置指標(biāo)等,以便得到資料時可以通知該視窗來使用資料。呼叫此函式後會馬上回到使用者的呼叫點并傳回一個 handle,此 handle 可用來辨別此非同步動作或用來取消此非同步動作。當(dāng)資料取得後,會送一個訊息到使用者指定的視窗。

(2) WSAAsyncGetHostByName():利用某一 host 的名稱來獲取該 host 的資料。 (非同步方式)

格 式: HANDLE PASCAL FAR WSAAsyncGetHostByName( HWND hWnd, unsigned int wMsg, const char FAR *name, char FAR *buf, int buflen );

參 數(shù):

hWnd 動作完成後,接受訊息的視窗 handle

wMsg 傳回視窗的訊息

name host 名稱

buf 存放 hostent 資料的區(qū)域

buflen buf 的大小

傳回值: 成功 - 代表此 Async 動作的 handle

失敗 - 0 (呼叫 WSAGetLastError() 可得知原因)

說明: 此函式是利用 host 名稱來獲取其他的資料,如 host 的位址、別名, 位址的型態(tài)、長度等。使用者呼叫此函式時必須傳入要接收資料的視窗handle、訊息代碼、資料的存放位置指標(biāo)等,以便得到資料時可以通知該視窗來使用資料。呼叫此函式後會馬上回到使用者的呼叫點并傳回一個 handle,此handle 可用來辨別此非同步動作或用來取消此非同步動作。當(dāng)資料取得後,會送一個訊息到使用者指定的視窗。

(3) WSAAsyncGetProtoByName():依照通訊協(xié)定的名稱來獲取該通訊協(xié)定的其他資料。(非同步方式)

格 式: HANDLE PASCAL FAR WSAAsyncGetProtoByName( HWND hWnd, unsigned int wMsg, const char FAR *name, char FAR *buf, int buflen );

參 數(shù): hWnd 動作完成後,接受訊息的視窗 handle

wMsg 傳回視窗的訊息

name 通訊協(xié)定名稱

buf 存放 protoent 資料的區(qū)域

buflen buf 的大小

傳回值: 成功 - 代表此 Async 動作的 handle

失敗 - 0 (呼叫 WSAGetLastError() 可得知原因)

說明: 利用通訊協(xié)定的名稱來得知該通訊協(xié)定的別名、編號等資料。使用者呼叫此函式時必須傳入要接收資料的視窗 handle、訊息代碼、資料的存放位置指標(biāo)等,以便得到資料時可以通知該視窗來使用資料。呼叫此函式後會馬上回到使用者的呼叫點并傳回一個 handle,此 handle可用來辨別此

?

轉(zhuǎn)載于:https://www.cnblogs.com/bigfish--/archive/2012/01/03/2311435.html

總結(jié)

以上是生活随笔為你收集整理的Winsock编程宝典(转帖)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

精品人妻人人做人人爽夜夜爽 | 婷婷综合久久中文字幕蜜桃三电影 | 丰满诱人的人妻3 | 国产精品毛多多水多 | 天天拍夜夜添久久精品 | 131美女爱做视频 | 图片区 小说区 区 亚洲五月 | 国产人成高清在线视频99最全资源 | 国产乡下妇女做爰 | 极品嫩模高潮叫床 | 亚洲精品国偷拍自产在线观看蜜桃 | 宝宝好涨水快流出来免费视频 | 久久国产精品萌白酱免费 | 国产口爆吞精在线视频 | 漂亮人妻洗澡被公强 日日躁 | 少妇愉情理伦片bd | 久久久精品456亚洲影院 | 中文字幕人成乱码熟女app | 国产偷抇久久精品a片69 | 天天拍夜夜添久久精品大 | 草草网站影院白丝内射 | 帮老师解开蕾丝奶罩吸乳网站 | 精品国精品国产自在久国产87 | 无码人妻av免费一区二区三区 | 久久精品一区二区三区四区 | 丝袜美腿亚洲一区二区 | 精品一区二区三区波多野结衣 | 日本又色又爽又黄的a片18禁 | 97se亚洲精品一区 | 男女猛烈xx00免费视频试看 | 无码精品人妻一区二区三区av | 宝宝好涨水快流出来免费视频 | 无遮挡国产高潮视频免费观看 | 亚洲欧美中文字幕5发布 | 97精品国产97久久久久久免费 | 久久精品女人的天堂av | 99久久精品日本一区二区免费 | 在线精品国产一区二区三区 | 久久久国产精品无码免费专区 | 久久www免费人成人片 | 人人妻人人澡人人爽人人精品 | 一个人看的视频www在线 | 久久久精品国产sm最大网站 | 天天做天天爱天天爽综合网 | 东京一本一道一二三区 | 国产人妻人伦精品1国产丝袜 | 国产成人精品久久亚洲高清不卡 | 国产偷自视频区视频 | 亚洲国产成人a精品不卡在线 | 色婷婷香蕉在线一区二区 | 丰满人妻一区二区三区免费视频 | 未满小14洗澡无码视频网站 | 少妇无码av无码专区在线观看 | 999久久久国产精品消防器材 | 国内精品人妻无码久久久影院 | 国产三级精品三级男人的天堂 | 综合人妻久久一区二区精品 | 日本一卡2卡3卡四卡精品网站 | 久久久无码中文字幕久... | 免费国产黄网站在线观看 | 精品国产国产综合精品 | 久久久中文久久久无码 | 午夜精品一区二区三区的区别 | 久久久精品456亚洲影院 | 成人无码视频免费播放 | 丰腴饱满的极品熟妇 | 97精品国产97久久久久久免费 | 成 人影片 免费观看 | 久久久久免费看成人影片 | 狂野欧美激情性xxxx | 国产舌乚八伦偷品w中 | 国产 精品 自在自线 | 国产av一区二区精品久久凹凸 | 国产农村妇女aaaaa视频 撕开奶罩揉吮奶头视频 | 亚洲日韩av一区二区三区四区 | 亚洲七七久久桃花影院 | 国产精品久久久久久无码 | 一本精品99久久精品77 | 亚洲精品无码国产 | 国产极品美女高潮无套在线观看 | 丝袜足控一区二区三区 | 日本丰满护士爆乳xxxx | 国产香蕉尹人综合在线观看 | 亚无码乱人伦一区二区 | 四虎4hu永久免费 | 国产精品鲁鲁鲁 | 人人爽人人澡人人人妻 | 欧美老人巨大xxxx做受 | 欧洲vodafone精品性 | 亚洲精品中文字幕久久久久 | 亚洲精品鲁一鲁一区二区三区 | 国产精品无码一区二区桃花视频 | 无码人妻少妇伦在线电影 | 麻豆av传媒蜜桃天美传媒 | 中文字幕色婷婷在线视频 | 偷窥日本少妇撒尿chinese | 人人澡人人透人人爽 | 日韩精品a片一区二区三区妖精 | 日本精品高清一区二区 | 久久亚洲精品中文字幕无男同 | 亚洲日本va午夜在线电影 | 娇妻被黑人粗大高潮白浆 | аⅴ资源天堂资源库在线 | 99riav国产精品视频 | 欧美亚洲日韩国产人成在线播放 | 国产成人无码av在线影院 | 亚洲精品成人福利网站 | 中文字幕中文有码在线 | 日本精品少妇一区二区三区 | 国产综合久久久久鬼色 | 亚洲性无码av中文字幕 | 久久精品一区二区三区四区 | 内射白嫩少妇超碰 | 国产成人无码专区 | 一本久久伊人热热精品中文字幕 | 永久免费观看美女裸体的网站 | 国产乱人伦app精品久久 国产在线无码精品电影网 国产国产精品人在线视 | 男女猛烈xx00免费视频试看 | 99在线 | 亚洲 | 欧美国产亚洲日韩在线二区 | 在线a亚洲视频播放在线观看 | 成人无码精品1区2区3区免费看 | 久久视频在线观看精品 | 亚洲一区二区三区四区 | 国产极品视觉盛宴 | 亚洲伊人久久精品影院 | 精品国产成人一区二区三区 | 人妻体内射精一区二区三四 | 两性色午夜视频免费播放 | 欧美性生交活xxxxxdddd | а天堂中文在线官网 | 国产精品美女久久久久av爽李琼 | 中文字幕无码日韩欧毛 | 精品久久久久久人妻无码中文字幕 | 欧美激情综合亚洲一二区 | 东京热男人av天堂 | 无码人妻少妇伦在线电影 | 中文字幕日韩精品一区二区三区 | 综合网日日天干夜夜久久 | 97色伦图片97综合影院 | 亚洲色大成网站www | 成人无码影片精品久久久 | aⅴ在线视频男人的天堂 | 波多野结衣av在线观看 | 国产精品毛片一区二区 | 午夜精品一区二区三区在线观看 | 久在线观看福利视频 | 伊人色综合久久天天小片 | 日日摸日日碰夜夜爽av | 欧美日韩在线亚洲综合国产人 | 亚洲色无码一区二区三区 | 国产精品亚洲а∨无码播放麻豆 | 无码中文字幕色专区 | 久久精品国产亚洲精品 | 中文字幕亚洲情99在线 | 欧美日本精品一区二区三区 | 成在人线av无码免观看麻豆 | 一区二区传媒有限公司 | 无码av免费一区二区三区试看 | 粗大的内捧猛烈进出视频 | 亚洲人成网站色7799 | 国产午夜精品一区二区三区嫩草 | 国产国产精品人在线视 | 亚洲国产精品一区二区美利坚 | 国产亚洲精品久久久久久国模美 | 国产亚洲人成a在线v网站 | 亚洲欧美综合区丁香五月小说 | 欧美放荡的少妇 | 国产精品久久久久影院嫩草 | 亚洲啪av永久无码精品放毛片 | 久久久亚洲欧洲日产国码αv | 午夜肉伦伦影院 | 成人欧美一区二区三区黑人免费 | 人人澡人摸人人添 | 欧美肥老太牲交大战 | 亚洲最大成人网站 | 熟女少妇人妻中文字幕 | 麻豆果冻传媒2021精品传媒一区下载 | 久久国产精品_国产精品 | 亚洲の无码国产の无码步美 | 国产情侣作爱视频免费观看 | 国产精品久久久久久亚洲毛片 | 国产人妻人伦精品1国产丝袜 | 久久久av男人的天堂 | 久久99精品久久久久久 | 色一情一乱一伦一区二区三欧美 | 人妻无码αv中文字幕久久琪琪布 | 成人影院yy111111在线观看 | 国产人妖乱国产精品人妖 | 成人一区二区免费视频 | 国产黄在线观看免费观看不卡 | 欧美色就是色 | 一个人看的视频www在线 | 亚洲 日韩 欧美 成人 在线观看 | 亚洲中文字幕在线无码一区二区 | 精品一区二区三区无码免费视频 | 色欲av亚洲一区无码少妇 | 无码一区二区三区在线观看 | 国语自产偷拍精品视频偷 | 精品无码一区二区三区的天堂 | 国产亚洲精品久久久闺蜜 | 国产精品久久国产三级国 | 亚洲国产精品一区二区美利坚 | 国产 浪潮av性色四虎 | 色婷婷综合中文久久一本 | 国产一区二区三区日韩精品 | 搡女人真爽免费视频大全 | 久久久久久国产精品无码下载 | 国产成人午夜福利在线播放 | 天堂а√在线地址中文在线 | 国产综合在线观看 | 美女扒开屁股让男人桶 | 久久久久久亚洲精品a片成人 | 国产精品高潮呻吟av久久 | 国产激情一区二区三区 | 国产人妻精品一区二区三区 | 天海翼激烈高潮到腰振不止 | 久久午夜夜伦鲁鲁片无码免费 | 鲁大师影院在线观看 | 久久久国产一区二区三区 | 亚洲a无码综合a国产av中文 | 图片小说视频一区二区 | 国产亚洲精品久久久久久久 | 天干天干啦夜天干天2017 | аⅴ资源天堂资源库在线 | 18禁止看的免费污网站 | 伊人久久婷婷五月综合97色 | 欧美日韩在线亚洲综合国产人 | 99精品久久毛片a片 | 曰韩少妇内射免费播放 | 人人爽人人爽人人片av亚洲 | 免费观看又污又黄的网站 | 国产免费久久精品国产传媒 | 熟女体下毛毛黑森林 | 中文字幕乱妇无码av在线 | 日本精品少妇一区二区三区 | 亚洲成a人片在线观看日本 | 亚洲精品美女久久久久久久 | 午夜男女很黄的视频 | 国产精品福利视频导航 | 欧美 丝袜 自拍 制服 另类 | 九九热爱视频精品 | 亚洲码国产精品高潮在线 | 久久精品国产一区二区三区 | 国产综合色产在线精品 | 欧美国产亚洲日韩在线二区 | 国产精品二区一区二区aⅴ污介绍 | 奇米影视888欧美在线观看 | 狠狠色噜噜狠狠狠7777奇米 | 美女张开腿让人桶 | 免费国产成人高清在线观看网站 | 中文字幕无码免费久久99 | 久久久久久九九精品久 | 欧美人与物videos另类 | 日本va欧美va欧美va精品 | 中文字幕乱码人妻无码久久 | 思思久久99热只有频精品66 | 久久99精品久久久久久动态图 | 国产内射老熟女aaaa | 国内揄拍国内精品少妇国语 | 少妇人妻偷人精品无码视频 | 欧美肥老太牲交大战 | 国产精品无套呻吟在线 | 国产亚洲欧美在线专区 | 精品一区二区三区无码免费视频 | 国产精品爱久久久久久久 | 国产精品美女久久久久av爽李琼 | 日本大香伊一区二区三区 | 漂亮人妻洗澡被公强 日日躁 | 亚洲人成影院在线无码按摩店 | 欧美怡红院免费全部视频 | 综合人妻久久一区二区精品 | 成 人 网 站国产免费观看 | 久久久久国色av免费观看性色 | 国内精品人妻无码久久久影院 | 免费男性肉肉影院 | 国内老熟妇对白xxxxhd | 国内精品人妻无码久久久影院蜜桃 | 国产精品亚洲一区二区三区喷水 | 亚洲熟女一区二区三区 | 蜜桃臀无码内射一区二区三区 | 亚洲色在线无码国产精品不卡 | 色老头在线一区二区三区 | 精品日本一区二区三区在线观看 | 精品无人区无码乱码毛片国产 | 永久免费观看国产裸体美女 | 久久无码中文字幕免费影院蜜桃 | 国产一区二区三区精品视频 | 无码精品人妻一区二区三区av | 国产乱人无码伦av在线a | 装睡被陌生人摸出水好爽 | 少妇太爽了在线观看 | 日韩精品无码一区二区中文字幕 | 国产97人人超碰caoprom | 久久精品女人的天堂av | 久久这里只有精品视频9 | 一二三四在线观看免费视频 | 狂野欧美性猛交免费视频 | 精品成人av一区二区三区 | 久久精品99久久香蕉国产色戒 | 久久精品人妻少妇一区二区三区 | 初尝人妻少妇中文字幕 | 亚洲а∨天堂久久精品2021 | 午夜福利试看120秒体验区 | 无码成人精品区在线观看 | 亚洲无人区一区二区三区 | 成人女人看片免费视频放人 | 红桃av一区二区三区在线无码av | 98国产精品综合一区二区三区 | 亚洲の无码国产の无码步美 | a片在线免费观看 | 人妻插b视频一区二区三区 | 无码中文字幕色专区 | 国产一区二区不卡老阿姨 | 亚洲色欲久久久综合网东京热 | 丰满少妇弄高潮了www | 性欧美大战久久久久久久 | 丝袜美腿亚洲一区二区 | 国产精品美女久久久 | 色妞www精品免费视频 | 2020久久香蕉国产线看观看 | 国产成人久久精品流白浆 | 午夜精品一区二区三区在线观看 | 国产亚洲精品久久久久久国模美 | 日本熟妇大屁股人妻 | 亚洲欧美国产精品专区久久 | 亚洲中文字幕成人无码 | 捆绑白丝粉色jk震动捧喷白浆 | 蜜桃av蜜臀av色欲av麻 999久久久国产精品消防器材 | 亚洲人亚洲人成电影网站色 | 乱码午夜-极国产极内射 | 国产乱人伦app精品久久 国产在线无码精品电影网 国产国产精品人在线视 | 久久久婷婷五月亚洲97号色 | 99er热精品视频 | 图片区 小说区 区 亚洲五月 | 国产在线无码精品电影网 | 久久精品国产99久久6动漫 | 精品 日韩 国产 欧美 视频 | 国产成人无码av在线影院 | 18无码粉嫩小泬无套在线观看 | 少妇太爽了在线观看 | 亚洲国产精华液网站w | 欧美三级a做爰在线观看 | 国产精品高潮呻吟av久久 | 高清国产亚洲精品自在久久 | 国产成人无码av片在线观看不卡 | 亚洲人成无码网www | а天堂中文在线官网 | 国产激情一区二区三区 | 成人精品视频一区二区三区尤物 | 激情内射亚州一区二区三区爱妻 | 老熟女重囗味hdxx69 | 国产在线一区二区三区四区五区 | 亚洲国产av精品一区二区蜜芽 | 露脸叫床粗话东北少妇 | 国产在线aaa片一区二区99 | 欧美大屁股xxxxhd黑色 | 亚洲国产欧美日韩精品一区二区三区 | 高清无码午夜福利视频 | 国产真实伦对白全集 | 国内老熟妇对白xxxxhd | 樱花草在线播放免费中文 | 成人免费无码大片a毛片 | 国产精品免费大片 | 国产亚av手机在线观看 | 日本xxxx色视频在线观看免费 | 欧美人妻一区二区三区 | 国产超碰人人爽人人做人人添 | 成人片黄网站色大片免费观看 | 黄网在线观看免费网站 | 久久国产精品二国产精品 | 一本色道婷婷久久欧美 | 欧美自拍另类欧美综合图片区 | 亚洲欧美精品aaaaaa片 | 国产黄在线观看免费观看不卡 | 国产av剧情md精品麻豆 | 久久无码中文字幕免费影院蜜桃 | 久久久久亚洲精品中文字幕 | 成年美女黄网站色大免费全看 | 久久久久久九九精品久 | 一个人看的视频www在线 | 亚洲最大成人网站 | 日本又色又爽又黄的a片18禁 | 真人与拘做受免费视频一 | 亚洲熟妇自偷自拍另类 | 精品久久久久久亚洲精品 | 爽爽影院免费观看 | 欧美熟妇另类久久久久久多毛 | 国产成人一区二区三区在线观看 | 九九热爱视频精品 | 日韩精品无码一区二区中文字幕 | 国产 精品 自在自线 | 青青青手机频在线观看 | 精品国产麻豆免费人成网站 | 亚洲国产精华液网站w | 一二三四在线观看免费视频 | 日韩精品无码免费一区二区三区 | 亚洲国产精华液网站w | 国产性猛交╳xxx乱大交 国产精品久久久久久无码 欧洲欧美人成视频在线 | 欧美日本免费一区二区三区 | 成年女人永久免费看片 | 日韩亚洲欧美中文高清在线 | 国语自产偷拍精品视频偷 | 日日干夜夜干 | 亚洲欧洲日本无在线码 | 国语精品一区二区三区 | 5858s亚洲色大成网站www | 人妻尝试又大又粗久久 | 久久精品国产99久久6动漫 | 成人欧美一区二区三区黑人 | 亚洲国产欧美日韩精品一区二区三区 | 日韩精品a片一区二区三区妖精 | 女人被爽到呻吟gif动态图视看 | 老太婆性杂交欧美肥老太 | yw尤物av无码国产在线观看 | 西西人体www44rt大胆高清 | 老司机亚洲精品影院 | 少妇愉情理伦片bd | 扒开双腿吃奶呻吟做受视频 | 夜夜夜高潮夜夜爽夜夜爰爰 | 中文字幕+乱码+中文字幕一区 | 人妻少妇精品久久 | 国产成人精品必看 | 欧美放荡的少妇 | 久久精品国产99精品亚洲 | 亚洲综合无码一区二区三区 | 激情内射亚州一区二区三区爱妻 | 成人无码精品一区二区三区 | 久久综合九色综合欧美狠狠 | 国产欧美精品一区二区三区 | 欧美人与善在线com | 色五月丁香五月综合五月 | 久久zyz资源站无码中文动漫 | 精品夜夜澡人妻无码av蜜桃 | 久久久久人妻一区精品色欧美 | 人人澡人人透人人爽 | 国产真实乱对白精彩久久 | 日韩精品久久久肉伦网站 | 狠狠亚洲超碰狼人久久 | 久久无码专区国产精品s | 欧美怡红院免费全部视频 | 欧美 亚洲 国产 另类 | 桃花色综合影院 | 学生妹亚洲一区二区 | 亚洲国产精品美女久久久久 | 久精品国产欧美亚洲色aⅴ大片 | 亚洲男人av天堂午夜在 | 久久久久成人精品免费播放动漫 | 亚洲成在人网站无码天堂 | 亚洲中文字幕成人无码 | 国产av无码专区亚洲awww | 久久久久久av无码免费看大片 | 一区二区三区高清视频一 | 亚洲va中文字幕无码久久不卡 | 国产特级毛片aaaaaa高潮流水 | 国产精品无码一区二区桃花视频 | 国产一区二区不卡老阿姨 | 国产亚洲欧美日韩亚洲中文色 | 亚洲精品国偷拍自产在线麻豆 | 午夜无码区在线观看 | 无码人妻丰满熟妇区毛片18 | 18无码粉嫩小泬无套在线观看 | 国产偷自视频区视频 | 午夜精品久久久内射近拍高清 | 国产卡一卡二卡三 | 国产在热线精品视频 | 伊人久久婷婷五月综合97色 | 波多野结衣乳巨码无在线观看 | 国产精品亚洲专区无码不卡 | 国精品人妻无码一区二区三区蜜柚 | 久久国内精品自在自线 | 天堂在线观看www | 永久黄网站色视频免费直播 | 日本熟妇乱子伦xxxx | 97夜夜澡人人爽人人喊中国片 | 窝窝午夜理论片影院 | 亚洲国产欧美在线成人 | 麻豆国产97在线 | 欧洲 | 精品一区二区不卡无码av | 国产后入清纯学生妹 | 久久五月精品中文字幕 | 蜜桃视频插满18在线观看 | 亚无码乱人伦一区二区 | 国内精品人妻无码久久久影院 | 国产电影无码午夜在线播放 | 粗大的内捧猛烈进出视频 | 麻豆国产人妻欲求不满谁演的 | 久久人妻内射无码一区三区 | 国产精品久久久久9999小说 | 亚洲午夜福利在线观看 | 十八禁真人啪啪免费网站 | v一区无码内射国产 | 高潮毛片无遮挡高清免费 | 97人妻精品一区二区三区 | 欧美日韩人成综合在线播放 | 鲁鲁鲁爽爽爽在线视频观看 | 久久伊人色av天堂九九小黄鸭 | 中国大陆精品视频xxxx | 丰满少妇熟乱xxxxx视频 | 清纯唯美经典一区二区 | 欧美一区二区三区视频在线观看 | 成人无码精品1区2区3区免费看 | 欧美乱妇无乱码大黄a片 | 亚洲人成影院在线无码按摩店 | 99精品无人区乱码1区2区3区 | 日本又色又爽又黄的a片18禁 | 国产内射爽爽大片视频社区在线 | 欧美亚洲日韩国产人成在线播放 | 2020久久香蕉国产线看观看 | 一本久久a久久精品vr综合 | 无码精品国产va在线观看dvd | 精品无码一区二区三区爱欲 | 麻豆国产人妻欲求不满 | 给我免费的视频在线观看 | 国内精品人妻无码久久久影院 | 成人无码视频免费播放 | 99精品视频在线观看免费 | 亚洲成av人综合在线观看 | 无码人妻黑人中文字幕 | 成年女人永久免费看片 | 精品人人妻人人澡人人爽人人 | 伊人久久大香线蕉午夜 | 在线视频网站www色 | 国产一区二区三区四区五区加勒比 | 成熟妇人a片免费看网站 | 精品国产一区二区三区四区在线看 | 荫蒂被男人添的好舒服爽免费视频 | 高清不卡一区二区三区 | 精品无码一区二区三区的天堂 | 国产凸凹视频一区二区 | 亚洲 激情 小说 另类 欧美 | 99久久精品午夜一区二区 | 亚洲色在线无码国产精品不卡 | av在线亚洲欧洲日产一区二区 | 天堂无码人妻精品一区二区三区 | 亚洲区欧美区综合区自拍区 | 国产特级毛片aaaaaa高潮流水 | 一个人看的www免费视频在线观看 | 午夜时刻免费入口 | 无码av免费一区二区三区试看 | 爱做久久久久久 | 伊人久久大香线蕉午夜 | 少妇人妻偷人精品无码视频 | 十八禁真人啪啪免费网站 | 久久99精品国产麻豆蜜芽 | 欧美老妇与禽交 | 亚洲爆乳大丰满无码专区 | 亚洲最大成人网站 | 亚洲欧美色中文字幕在线 | 人妻插b视频一区二区三区 | 色婷婷综合激情综在线播放 | 成人综合网亚洲伊人 | 国产尤物精品视频 | 性欧美大战久久久久久久 | 久久午夜无码鲁丝片午夜精品 | 任你躁国产自任一区二区三区 | 黑人巨大精品欧美一区二区 | 亚洲综合久久一区二区 | 国产电影无码午夜在线播放 | 国产午夜无码精品免费看 | 天天燥日日燥 | 亚洲国产精品美女久久久久 | 亚洲熟妇色xxxxx欧美老妇 | 国产精品福利视频导航 | 无码成人精品区在线观看 | 搡女人真爽免费视频大全 | 在线a亚洲视频播放在线观看 | 骚片av蜜桃精品一区 | 久久精品国产一区二区三区 | 九九在线中文字幕无码 | 国产av一区二区三区最新精品 | 久久 国产 尿 小便 嘘嘘 | 少妇太爽了在线观看 | 亚洲精品一区三区三区在线观看 | 色综合天天综合狠狠爱 | 荡女精品导航 | 国产精品久久久午夜夜伦鲁鲁 | 欧美人与禽zoz0性伦交 | 国产精品亚洲а∨无码播放麻豆 | 精品少妇爆乳无码av无码专区 | 免费无码的av片在线观看 | 无码纯肉视频在线观看 | 亚洲精品成a人在线观看 | 最新国产麻豆aⅴ精品无码 | 内射爽无广熟女亚洲 | 欧美精品国产综合久久 | 国产成人无码区免费内射一片色欲 | 国产激情艳情在线看视频 | av无码久久久久不卡免费网站 | 亚洲毛片av日韩av无码 | 丝袜 中出 制服 人妻 美腿 | 青青青爽视频在线观看 | 久久国产36精品色熟妇 | 久久精品人人做人人综合试看 | 国产亚洲tv在线观看 | 色综合视频一区二区三区 | 四十如虎的丰满熟妇啪啪 | 国产精品美女久久久久av爽李琼 | 成人性做爰aaa片免费看 | 久久精品国产精品国产精品污 | 国语精品一区二区三区 | 国产精品18久久久久久麻辣 | 中文字幕日产无线码一区 | 国产亚洲精品久久久久久国模美 | 亚洲成色在线综合网站 | 日产精品高潮呻吟av久久 | 人妻少妇精品无码专区二区 | 一本久道久久综合狠狠爱 | 国产成人人人97超碰超爽8 | 亚洲精品综合一区二区三区在线 | 欧美日韩精品 | 国产日产欧产精品精品app | 久久99久久99精品中文字幕 | 东京无码熟妇人妻av在线网址 | 亚洲毛片av日韩av无码 | 永久免费观看国产裸体美女 | 亚洲日本va中文字幕 | 国产精品无码永久免费888 | 亚洲国产精品成人久久蜜臀 | 三上悠亚人妻中文字幕在线 | 女人被爽到呻吟gif动态图视看 | 牛和人交xxxx欧美 | 老子影院午夜精品无码 | 高潮毛片无遮挡高清免费 | 国产又爽又黄又刺激的视频 | 国产做国产爱免费视频 | 国产午夜无码视频在线观看 | 兔费看少妇性l交大片免费 | 暴力强奷在线播放无码 | 日韩亚洲欧美精品综合 | 精品亚洲成av人在线观看 | 国产精品无码一区二区桃花视频 | 久久久婷婷五月亚洲97号色 | 一本色道久久综合狠狠躁 | 欧美兽交xxxx×视频 | 丰满少妇人妻久久久久久 | 秋霞成人午夜鲁丝一区二区三区 | 亚洲中文字幕成人无码 | 国产午夜福利100集发布 | 国产亚洲美女精品久久久2020 | 亚洲 高清 成人 动漫 | 人人澡人人透人人爽 | 国产精品欧美成人 | 国产精品久久久久久久影院 | 精品水蜜桃久久久久久久 | 4hu四虎永久在线观看 | 性色av无码免费一区二区三区 | 女人高潮内射99精品 | 久久婷婷五月综合色国产香蕉 | 人人爽人人澡人人高潮 | 国产精品嫩草久久久久 | 特黄特色大片免费播放器图片 | 少女韩国电视剧在线观看完整 | 欧美日韩一区二区免费视频 | 久久99久久99精品中文字幕 | 色欲久久久天天天综合网精品 | a片免费视频在线观看 | 免费无码一区二区三区蜜桃大 | 久久熟妇人妻午夜寂寞影院 | 国产亚洲精品久久久久久 | 精品偷自拍另类在线观看 | 国产人妻人伦精品 | 欧美一区二区三区视频在线观看 | 国产精品无码成人午夜电影 | 欧美黑人乱大交 | 强辱丰满人妻hd中文字幕 | 男人扒开女人内裤强吻桶进去 | 欧洲欧美人成视频在线 | aⅴ亚洲 日韩 色 图网站 播放 | 精品国产成人一区二区三区 | 国产无套内射久久久国产 | 精品偷自拍另类在线观看 | 亚洲一区二区三区偷拍女厕 | 三上悠亚人妻中文字幕在线 | 日本精品人妻无码77777 天堂一区人妻无码 | 日本一区二区三区免费高清 | 亚洲成a人片在线观看日本 | 性欧美牲交xxxxx视频 | 欧美精品免费观看二区 | 午夜熟女插插xx免费视频 | 国产精品亚洲一区二区三区喷水 | 在线观看国产午夜福利片 | 日本肉体xxxx裸交 | 日韩人妻系列无码专区 | 又大又紧又粉嫩18p少妇 | 玩弄少妇高潮ⅹxxxyw | 成人片黄网站色大片免费观看 | 熟妇人妻中文av无码 | 无码任你躁久久久久久久 | 人人妻人人澡人人爽人人精品浪潮 | 三级4级全黄60分钟 | 国产成人无码av在线影院 | 激情内射亚州一区二区三区爱妻 | 少妇性l交大片 | 荫蒂添的好舒服视频囗交 | 又大又硬又爽免费视频 | 欧美日韩人成综合在线播放 | 精品国产国产综合精品 | 精品久久久无码中文字幕 | 成熟妇人a片免费看网站 | 麻豆果冻传媒2021精品传媒一区下载 | 中文无码成人免费视频在线观看 | 一本久道久久综合狠狠爱 | 日本成熟视频免费视频 | 国产高清不卡无码视频 | 久久久久久久女国产乱让韩 | 领导边摸边吃奶边做爽在线观看 | 国产尤物精品视频 | 国产精品无码成人午夜电影 | 2020最新国产自产精品 | 国产av人人夜夜澡人人爽麻豆 | 久热国产vs视频在线观看 | 亚洲日韩av一区二区三区四区 | 久久久精品成人免费观看 | 中文字幕日产无线码一区 | 水蜜桃av无码 | 成人aaa片一区国产精品 | 欧美黑人性暴力猛交喷水 | 丁香花在线影院观看在线播放 | 亚洲一区二区三区播放 | 亚洲中文字幕久久无码 | 久久综合九色综合97网 | 国产精品久久久久影院嫩草 | 性色av无码免费一区二区三区 | 精品一区二区三区波多野结衣 | 日本在线高清不卡免费播放 | 久久久久99精品成人片 | av人摸人人人澡人人超碰下载 | ass日本丰满熟妇pics | 天天摸天天透天天添 | 一个人看的视频www在线 | 国产精品无码永久免费888 | 狠狠躁日日躁夜夜躁2020 | 一本色道久久综合亚洲精品不卡 | 久久无码人妻影院 | 最近免费中文字幕中文高清百度 | 一区二区三区高清视频一 | 人人妻人人澡人人爽欧美精品 | 国产亚洲欧美日韩亚洲中文色 | 日韩精品a片一区二区三区妖精 | 丝袜美腿亚洲一区二区 | 中文字幕无线码免费人妻 | 少女韩国电视剧在线观看完整 | 永久黄网站色视频免费直播 | 中文字幕乱码亚洲无线三区 | 婷婷丁香五月天综合东京热 | 国产sm调教视频在线观看 | 国产精品人人妻人人爽 | 天干天干啦夜天干天2017 | 中文精品无码中文字幕无码专区 | 少妇无码一区二区二三区 | 亚洲中文字幕无码中字 | 国产精品美女久久久久av爽李琼 | 1000部夫妻午夜免费 | 一本加勒比波多野结衣 | 在线a亚洲视频播放在线观看 | 西西人体www44rt大胆高清 | aⅴ亚洲 日韩 色 图网站 播放 | 国产精品美女久久久久av爽李琼 | 天天拍夜夜添久久精品 | 内射巨臀欧美在线视频 | 亚洲一区av无码专区在线观看 | 无码播放一区二区三区 | 51国偷自产一区二区三区 | 中文久久乱码一区二区 | 中文字幕乱码人妻无码久久 | 亚洲人成无码网www | 99久久精品日本一区二区免费 | 人人妻在人人 | 国产精品久久久午夜夜伦鲁鲁 | 老司机亚洲精品影院无码 | 亚洲男人av香蕉爽爽爽爽 | 欧洲欧美人成视频在线 | 欧美日韩色另类综合 | 免费视频欧美无人区码 | 高清无码午夜福利视频 | 欧美性猛交xxxx富婆 | 国产精品亚洲五月天高清 | 国产精品久久久久久亚洲影视内衣 | 欧美精品一区二区精品久久 | 少妇人妻偷人精品无码视频 | 高潮毛片无遮挡高清免费 | 精品乱码久久久久久久 | 国产猛烈高潮尖叫视频免费 | 国产av一区二区三区最新精品 | 中文无码精品a∨在线观看不卡 | 欧美性生交xxxxx久久久 | 国产成人精品必看 | 亚洲国产高清在线观看视频 | 色婷婷av一区二区三区之红樱桃 | 色综合久久中文娱乐网 | av人摸人人人澡人人超碰下载 | 中文字幕人妻无码一夲道 | 精品国产精品久久一区免费式 | 亚洲精品一区二区三区婷婷月 | 国产成人无码一二三区视频 | 国产香蕉尹人综合在线观看 | 麻花豆传媒剧国产免费mv在线 | 欧美肥老太牲交大战 | 一本精品99久久精品77 | 伊人久久婷婷五月综合97色 | 中文字幕无码免费久久9一区9 | 国产精品久免费的黄网站 | 亚洲午夜久久久影院 | 扒开双腿疯狂进出爽爽爽视频 | 特级做a爰片毛片免费69 | 亚洲国产成人a精品不卡在线 | 性啪啪chinese东北女人 | 国产97在线 | 亚洲 | 国产精品久久久一区二区三区 | 女人被男人躁得好爽免费视频 | 国产人妻精品一区二区三区不卡 | 2020久久香蕉国产线看观看 | 日日鲁鲁鲁夜夜爽爽狠狠 | 98国产精品综合一区二区三区 | av在线亚洲欧洲日产一区二区 | 在线成人www免费观看视频 | 成熟女人特级毛片www免费 | 欧美日韩在线亚洲综合国产人 | 久久久av男人的天堂 | 国产香蕉尹人视频在线 | 成人女人看片免费视频放人 | 东京热男人av天堂 | 日韩av激情在线观看 | 午夜福利电影 | 性欧美videos高清精品 | 国产精品嫩草久久久久 | 又湿又紧又大又爽a视频国产 | 5858s亚洲色大成网站www | 亚洲男女内射在线播放 | 精品成在人线av无码免费看 | 超碰97人人做人人爱少妇 | 未满小14洗澡无码视频网站 | 欧美一区二区三区视频在线观看 | 人人妻人人澡人人爽欧美精品 | 国产婷婷色一区二区三区在线 | 东北女人啪啪对白 | 日产精品99久久久久久 | 精品无码一区二区三区爱欲 | 中文字幕无码乱人伦 | 国产亚洲精品久久久ai换 | 国产办公室秘书无码精品99 | 国产又粗又硬又大爽黄老大爷视 | 九九久久精品国产免费看小说 | 嫩b人妻精品一区二区三区 | 扒开双腿疯狂进出爽爽爽视频 | 7777奇米四色成人眼影 | 中文字幕av日韩精品一区二区 | 国产精品久久久av久久久 | 一本久久a久久精品vr综合 | 十八禁真人啪啪免费网站 | 午夜精品久久久久久久 | 欧美性黑人极品hd | 曰韩少妇内射免费播放 | 亚洲国产精品无码一区二区三区 | 中文字幕无码av激情不卡 | 欧美第一黄网免费网站 | 久久精品国产99精品亚洲 | 两性色午夜免费视频 | 红桃av一区二区三区在线无码av | 日日麻批免费40分钟无码 | a片免费视频在线观看 | 亚洲综合久久一区二区 | 青青青手机频在线观看 | 亚洲国产精品无码一区二区三区 | 性欧美大战久久久久久久 | 久久国产36精品色熟妇 | 超碰97人人做人人爱少妇 | 午夜精品久久久久久久 | 国产成人精品优优av | 丁香花在线影院观看在线播放 | 久久国产精品偷任你爽任你 | 欧美日韩综合一区二区三区 | 亚洲乱码日产精品bd | 久久久久久久久888 | 日本大香伊一区二区三区 | 最新国产乱人伦偷精品免费网站 | 午夜男女很黄的视频 | 东京热无码av男人的天堂 | 欧美性黑人极品hd | 亚洲天堂2017无码中文 | 午夜无码人妻av大片色欲 | 黑人粗大猛烈进出高潮视频 | 女高中生第一次破苞av | 久久久久成人精品免费播放动漫 | 麻豆果冻传媒2021精品传媒一区下载 | 在线观看国产一区二区三区 | 午夜福利不卡在线视频 | 无码人妻出轨黑人中文字幕 | 天堂亚洲2017在线观看 | 少妇太爽了在线观看 | 蜜桃臀无码内射一区二区三区 | 黑人巨大精品欧美一区二区 | 狂野欧美激情性xxxx | 偷窥村妇洗澡毛毛多 | 亚洲自偷自拍另类第1页 | 亚洲午夜无码久久 | 大地资源中文第3页 | 国产精品无码mv在线观看 | 亚洲欧美综合区丁香五月小说 | 久久精品视频在线看15 | 欧美 日韩 人妻 高清 中文 | 日本护士xxxxhd少妇 | 国产午夜无码精品免费看 | 天海翼激烈高潮到腰振不止 | 久久精品人人做人人综合试看 | 人人妻人人澡人人爽精品欧美 | 亚洲精品久久久久久久久久久 | 国产日产欧产精品精品app | 成人女人看片免费视频放人 | 欧美 亚洲 国产 另类 | 欧美丰满老熟妇xxxxx性 | 99er热精品视频 | 久9re热视频这里只有精品 | 国产精品福利视频导航 | 久久久无码中文字幕久... | 国产福利视频一区二区 | 国产人妻久久精品二区三区老狼 | 国产9 9在线 | 中文 | 婷婷丁香五月天综合东京热 | 久久精品成人欧美大片 | 欧美老妇交乱视频在线观看 | 亚洲精品久久久久久一区二区 | 男女超爽视频免费播放 | 日韩精品乱码av一区二区 | 国产免费观看黄av片 | 激情亚洲一区国产精品 | 欧美日本免费一区二区三区 | 久久精品国产亚洲精品 | 久久婷婷五月综合色国产香蕉 | 天天综合网天天综合色 | 欧美35页视频在线观看 | 九九久久精品国产免费看小说 | 精品无人区无码乱码毛片国产 | 东京无码熟妇人妻av在线网址 | 亚洲aⅴ无码成人网站国产app | 影音先锋中文字幕无码 | 无码国产乱人伦偷精品视频 | 四虎永久在线精品免费网址 | 亚洲春色在线视频 | 野外少妇愉情中文字幕 | 18无码粉嫩小泬无套在线观看 | 亚洲国产成人a精品不卡在线 | 亚洲日本va中文字幕 | 国产亚洲精品久久久久久 | 在线视频网站www色 | 欧美兽交xxxx×视频 | 国产女主播喷水视频在线观看 | 国产婷婷色一区二区三区在线 | 鲁一鲁av2019在线 | 欧洲美熟女乱又伦 | 双乳奶水饱满少妇呻吟 | 亚洲国产成人av在线观看 | 九九久久精品国产免费看小说 | 亚洲の无码国产の无码影院 | 亚洲国产精华液网站w | 中文字幕人妻无码一区二区三区 | 色婷婷久久一区二区三区麻豆 | 曰韩无码二三区中文字幕 | 亚洲国产欧美国产综合一区 | 日韩精品乱码av一区二区 | 精品久久久久久亚洲精品 | 色婷婷香蕉在线一区二区 | 精品国产精品久久一区免费式 | 亚洲一区二区三区四区 | 国产精品久久久午夜夜伦鲁鲁 | 国产97人人超碰caoprom | 欧美成人午夜精品久久久 | 性欧美videos高清精品 | 黑人巨大精品欧美一区二区 | 欧美午夜特黄aaaaaa片 | 亚洲综合无码一区二区三区 | 内射老妇bbwx0c0ck | 全球成人中文在线 | 久久97精品久久久久久久不卡 | 国产精品对白交换视频 | 精品久久久久香蕉网 | 扒开双腿疯狂进出爽爽爽视频 | 国产肉丝袜在线观看 | 国产欧美精品一区二区三区 | 久久婷婷五月综合色国产香蕉 | 国产97人人超碰caoprom | 波多野结衣 黑人 | 亚洲国产午夜精品理论片 | 激情综合激情五月俺也去 | 久久亚洲中文字幕精品一区 | 免费中文字幕日韩欧美 | 精品久久久无码中文字幕 | 中文字幕无码人妻少妇免费 | 日本精品高清一区二区 | 夜精品a片一区二区三区无码白浆 | 内射爽无广熟女亚洲 | 精品一二三区久久aaa片 | 小鲜肉自慰网站xnxx | 999久久久国产精品消防器材 | 国产激情艳情在线看视频 | 国产精品18久久久久久麻辣 | 国产69精品久久久久app下载 | 亚洲 激情 小说 另类 欧美 | 青青草原综合久久大伊人精品 | 波多野结衣 黑人 | ass日本丰满熟妇pics | 日韩欧美群交p片內射中文 | 国产欧美精品一区二区三区 | 久激情内射婷内射蜜桃人妖 | 少妇一晚三次一区二区三区 | 欧美xxxxx精品 | 麻豆av传媒蜜桃天美传媒 | 成人无码精品1区2区3区免费看 | 国产成人久久精品流白浆 | 偷窥日本少妇撒尿chinese | 未满成年国产在线观看 | 动漫av网站免费观看 | 狠狠色噜噜狠狠狠狠7777米奇 | 天天躁夜夜躁狠狠是什么心态 | 在线看片无码永久免费视频 | 色综合视频一区二区三区 | 欧美日韩视频无码一区二区三 | 欧美阿v高清资源不卡在线播放 | 亚洲无人区一区二区三区 | 亚洲人交乣女bbw | 欧美性生交活xxxxxdddd | 精品国产一区二区三区av 性色 | 色偷偷人人澡人人爽人人模 | 国产又爽又猛又粗的视频a片 | 国产精品va在线播放 | 男女下面进入的视频免费午夜 | 中文字幕无线码 | 人妻天天爽夜夜爽一区二区 | 黑人粗大猛烈进出高潮视频 | 国产成人精品优优av | 国产精品毛多多水多 | 黑森林福利视频导航 | 夜夜夜高潮夜夜爽夜夜爰爰 | 97夜夜澡人人双人人人喊 | 色窝窝无码一区二区三区色欲 | 婷婷六月久久综合丁香 | 好屌草这里只有精品 | 领导边摸边吃奶边做爽在线观看 | 无遮挡国产高潮视频免费观看 | 国产成人一区二区三区在线观看 | 亚洲阿v天堂在线 | 性欧美牲交在线视频 | 国产内射爽爽大片视频社区在线 | 精品偷拍一区二区三区在线看 | 青草青草久热国产精品 | 成人精品视频一区二区 | 国语自产偷拍精品视频偷 | 亚洲午夜久久久影院 | 成人亚洲精品久久久久 | 精品aⅴ一区二区三区 | 少妇厨房愉情理9仑片视频 | 日本一卡2卡3卡4卡无卡免费网站 国产一区二区三区影院 | 国产精品人人爽人人做我的可爱 | 国产精品沙发午睡系列 | 国内精品一区二区三区不卡 | 国产精品自产拍在线观看 | 久久久久久国产精品无码下载 | 国产情侣作爱视频免费观看 | 一区二区三区高清视频一 | 男人的天堂2018无码 | 97无码免费人妻超级碰碰夜夜 | 国产黄在线观看免费观看不卡 | 免费网站看v片在线18禁无码 | 色婷婷久久一区二区三区麻豆 | 国产精品免费大片 | 精品久久久久久人妻无码中文字幕 | 免费无码av一区二区 | 粉嫩少妇内射浓精videos | 波多野结衣aⅴ在线 | 性色av无码免费一区二区三区 | 一个人免费观看的www视频 | 强伦人妻一区二区三区视频18 | 少妇一晚三次一区二区三区 | 日韩av激情在线观看 | 奇米综合四色77777久久 东京无码熟妇人妻av在线网址 | 丰满人妻翻云覆雨呻吟视频 | 丰满岳乱妇在线观看中字无码 | 性史性农村dvd毛片 | 久久亚洲中文字幕无码 | 东北女人啪啪对白 | 亚洲中文字幕成人无码 | 国产人妻人伦精品 | 欧美猛少妇色xxxxx | 国内少妇偷人精品视频免费 | 国产女主播喷水视频在线观看 | 国产人妻大战黑人第1集 | 亚洲无人区午夜福利码高清完整版 | 亚洲色大成网站www | 亚洲一区二区三区四区 | 人人妻人人藻人人爽欧美一区 | 国内揄拍国内精品少妇国语 | 亚洲精品一区二区三区婷婷月 | 久久综合狠狠综合久久综合88 | 亚洲精品久久久久中文第一幕 | 一本久久a久久精品亚洲 | 红桃av一区二区三区在线无码av | 亚洲国产精品毛片av不卡在线 | 精品久久久无码中文字幕 | 久久久精品456亚洲影院 | 日本又色又爽又黄的a片18禁 | 无码国内精品人妻少妇 | 人人爽人人澡人人高潮 | 牲欲强的熟妇农村老妇女 | 午夜熟女插插xx免费视频 | 亚洲自偷自拍另类第1页 | 久久亚洲中文字幕精品一区 | 中文字幕日韩精品一区二区三区 | 少妇的肉体aa片免费 | 日韩精品久久久肉伦网站 | 欧美丰满老熟妇xxxxx性 | 无码中文字幕色专区 | 日本一卡二卡不卡视频查询 | 人妻无码αv中文字幕久久琪琪布 | 国产乱人伦偷精品视频 | 秋霞成人午夜鲁丝一区二区三区 | 亚洲精品国产a久久久久久 | 久久国产精品_国产精品 | 亚洲一区二区三区香蕉 | 国产香蕉尹人综合在线观看 | 国产网红无码精品视频 | 欧美国产日韩亚洲中文 | 亚洲一区av无码专区在线观看 | 国产偷自视频区视频 | 熟女少妇在线视频播放 | 乱人伦人妻中文字幕无码久久网 | 99久久精品无码一区二区毛片 | 中文字幕乱码亚洲无线三区 | 中文精品久久久久人妻不卡 | 久久精品国产精品国产精品污 | 伊人久久大香线蕉亚洲 | 成人毛片一区二区 | 亚洲国产av美女网站 | 牛和人交xxxx欧美 | 亚洲自偷自拍另类第1页 | 免费人成网站视频在线观看 | 欧美熟妇另类久久久久久不卡 | 亚洲欧美综合区丁香五月小说 | 女人被男人躁得好爽免费视频 | 日韩精品乱码av一区二区 | 牲欲强的熟妇农村老妇女 | 夜夜夜高潮夜夜爽夜夜爰爰 | 51国偷自产一区二区三区 | 婷婷六月久久综合丁香 | 免费播放一区二区三区 | 少妇被粗大的猛进出69影院 | 欧美黑人巨大xxxxx | 国产精品久久久久无码av色戒 | 麻花豆传媒剧国产免费mv在线 | 国产亚洲日韩欧美另类第八页 | 亚洲国精产品一二二线 | 亚洲色欲色欲欲www在线 | 暴力强奷在线播放无码 | 97无码免费人妻超级碰碰夜夜 | 国产97在线 | 亚洲 | 老子影院午夜精品无码 | 久久综合九色综合欧美狠狠 | 久久精品国产日本波多野结衣 | 国产人妖乱国产精品人妖 | 内射爽无广熟女亚洲 | 亚洲精品国偷拍自产在线麻豆 | 国产人妻人伦精品 | 色婷婷综合中文久久一本 | 小泽玛莉亚一区二区视频在线 | 成人三级无码视频在线观看 | 无码人妻av免费一区二区三区 | 成熟女人特级毛片www免费 | 三级4级全黄60分钟 | 亚洲熟妇色xxxxx欧美老妇 | 国产无遮挡吃胸膜奶免费看 | 久久精品中文字幕大胸 | 婷婷五月综合激情中文字幕 | 亚洲色www成人永久网址 | 日韩精品成人一区二区三区 | 亚洲爆乳无码专区 | 青青久在线视频免费观看 | 亚洲の无码国产の无码步美 | 国产偷自视频区视频 | 蜜桃av抽搐高潮一区二区 | 国产一区二区三区日韩精品 | 亚洲熟熟妇xxxx | 中文字幕乱码亚洲无线三区 | 国产精品亚洲lv粉色 | 亚洲另类伦春色综合小说 | 综合激情五月综合激情五月激情1 | 色偷偷av老熟女 久久精品人妻少妇一区二区三区 | 国产精品igao视频网 | 日本高清一区免费中文视频 | 精品国产一区二区三区av 性色 | 亚洲精品国产品国语在线观看 | 一本大道伊人av久久综合 | 婷婷五月综合激情中文字幕 | 国内精品久久毛片一区二区 | 日韩亚洲欧美中文高清在线 | 强伦人妻一区二区三区视频18 | 内射欧美老妇wbb | 激情内射亚州一区二区三区爱妻 | 亚洲码国产精品高潮在线 | 全黄性性激高免费视频 | 欧美阿v高清资源不卡在线播放 | 亚洲经典千人经典日产 | 少妇性俱乐部纵欲狂欢电影 | 国产无套粉嫩白浆在线 | 国产亚洲美女精品久久久2020 | 久久久av男人的天堂 | 中文字幕日韩精品一区二区三区 | 日本乱人伦片中文三区 | 国产乱子伦视频在线播放 | 国产精品久久久久久亚洲毛片 | 亚洲区欧美区综合区自拍区 | 午夜无码区在线观看 | 撕开奶罩揉吮奶头视频 | 亚洲男人av香蕉爽爽爽爽 | 日本成熟视频免费视频 | 麻豆精产国品 | 久久精品99久久香蕉国产色戒 | 国产精品亚洲五月天高清 | 国产av人人夜夜澡人人爽麻豆 | 亚洲午夜久久久影院 | 97夜夜澡人人爽人人喊中国片 | 亚洲综合精品香蕉久久网 | 亚洲日韩av一区二区三区中文 | 午夜精品一区二区三区的区别 | 丰满少妇高潮惨叫视频 | 十八禁真人啪啪免费网站 | 久久精品无码一区二区三区 | 亚洲成a人片在线观看日本 | 国产精品igao视频网 | 人人妻人人澡人人爽欧美精品 | 婷婷综合久久中文字幕蜜桃三电影 | 欧美丰满老熟妇xxxxx性 | 免费人成在线观看网站 | 老子影院午夜伦不卡 | 亚洲国产高清在线观看视频 | 国产成人综合色在线观看网站 | 激情内射亚州一区二区三区爱妻 | 亚洲成色www久久网站 | 波多野结衣av一区二区全免费观看 | 日日摸日日碰夜夜爽av | 国产亚洲欧美在线专区 | 色五月丁香五月综合五月 | 最新国产乱人伦偷精品免费网站 | 午夜不卡av免费 一本久久a久久精品vr综合 | 日本精品少妇一区二区三区 | 300部国产真实乱 | 久久久久成人片免费观看蜜芽 | 国产成人综合色在线观看网站 | 亚洲の无码国产の无码步美 | 熟女体下毛毛黑森林 | 国产精品久久国产三级国 | 俄罗斯老熟妇色xxxx | 国产绳艺sm调教室论坛 | 奇米综合四色77777久久 东京无码熟妇人妻av在线网址 | 国产精品99久久精品爆乳 | 熟妇人妻无乱码中文字幕 | 亚洲国产精品无码久久久久高潮 | 丰腴饱满的极品熟妇 | 国产明星裸体无码xxxx视频 | 国产av人人夜夜澡人人爽麻豆 | 丰满岳乱妇在线观看中字无码 | 亚洲精品一区二区三区在线观看 | 国产手机在线αⅴ片无码观看 | 国产后入清纯学生妹 | 国产成人一区二区三区别 | 精品成在人线av无码免费看 | 97久久国产亚洲精品超碰热 | 国产免费观看黄av片 | 久久亚洲国产成人精品性色 | 天天av天天av天天透 | 女人被男人躁得好爽免费视频 | 在线观看欧美一区二区三区 | 久久99热只有频精品8 | 中文亚洲成a人片在线观看 | 色综合久久久无码网中文 | 人人妻人人澡人人爽人人精品浪潮 | 鲁大师影院在线观看 | 久久www免费人成人片 | 高中生自慰www网站 | 人人澡人人透人人爽 | 荫蒂被男人添的好舒服爽免费视频 | 中文精品久久久久人妻不卡 | 亚洲国产精华液网站w | 国产午夜手机精彩视频 | 无码国产激情在线观看 | 中文字幕 人妻熟女 | 大肉大捧一进一出视频出来呀 | 一区二区三区乱码在线 | 欧洲 | 亚洲阿v天堂在线 | 亚洲国产高清在线观看视频 | 清纯唯美经典一区二区 | 国内揄拍国内精品少妇国语 | 日本精品少妇一区二区三区 | 亚洲第一无码av无码专区 | 国产成人无码av一区二区 | 高潮毛片无遮挡高清免费视频 | 麻豆国产97在线 | 欧洲 | 国产在热线精品视频 | 樱花草在线社区www | 日韩亚洲欧美精品综合 | 丰满岳乱妇在线观看中字无码 | 欧美乱妇无乱码大黄a片 | 装睡被陌生人摸出水好爽 | 在线视频网站www色 | 欧美成人家庭影院 | 久久精品人人做人人综合试看 | 精品一二三区久久aaa片 | 国产特级毛片aaaaaa高潮流水 | 亚洲人成网站免费播放 | 亚洲 另类 在线 欧美 制服 | 亚洲aⅴ无码成人网站国产app | 成人欧美一区二区三区黑人 | 国产亚洲欧美日韩亚洲中文色 | 日本肉体xxxx裸交 | 日日摸天天摸爽爽狠狠97 | 男人和女人高潮免费网站 | 亚洲男人av天堂午夜在 | 国产亚洲精品久久久久久大师 | 国产精品丝袜黑色高跟鞋 | 日本一卡二卡不卡视频查询 | 永久免费精品精品永久-夜色 | 人妻少妇精品无码专区二区 | 日本一卡2卡3卡4卡无卡免费网站 国产一区二区三区影院 | 熟女俱乐部五十路六十路av | 人妻少妇精品无码专区动漫 | 中文字幕人妻无码一夲道 | 欧美三级不卡在线观看 | 国产人成高清在线视频99最全资源 | 97精品国产97久久久久久免费 | 又黄又爽又色的视频 | 99久久婷婷国产综合精品青草免费 | 熟妇女人妻丰满少妇中文字幕 | 国产特级毛片aaaaaaa高清 | 亚洲成av人片在线观看无码不卡 | 国产亚洲精品久久久久久久久动漫 | 色综合久久网 | 四虎国产精品一区二区 | 思思久久99热只有频精品66 | 亚洲国产精华液网站w | 亚洲欧美国产精品专区久久 | 久久99国产综合精品 | 男人的天堂2018无码 | 亚洲中文字幕久久无码 | 亚洲国产欧美国产综合一区 | 亚洲精品综合五月久久小说 | 色婷婷欧美在线播放内射 | 国产香蕉尹人综合在线观看 | 亚洲日韩av一区二区三区四区 | 中文字幕+乱码+中文字幕一区 | 国产在线精品一区二区三区直播 | 亚洲精品国产a久久久久久 | 国产亚洲精品久久久久久 | 亚洲码国产精品高潮在线 | 午夜福利一区二区三区在线观看 | 国语自产偷拍精品视频偷 | 亚洲另类伦春色综合小说 | 午夜精品一区二区三区的区别 | 久久精品国产精品国产精品污 | 纯爱无遮挡h肉动漫在线播放 | 久久99精品国产.久久久久 | 少妇人妻av毛片在线看 | 少女韩国电视剧在线观看完整 | 国产又爽又黄又刺激的视频 | 国产午夜精品一区二区三区嫩草 | 天堂а√在线地址中文在线 | 激情五月综合色婷婷一区二区 | 亚洲 a v无 码免 费 成 人 a v | 影音先锋中文字幕无码 | 丝袜人妻一区二区三区 | 日本欧美一区二区三区乱码 | 久久综合给合久久狠狠狠97色 | 亚洲色欲色欲欲www在线 | 国产成人一区二区三区别 | 色婷婷香蕉在线一区二区 | 欧美亚洲国产一区二区三区 | 国产精品多人p群无码 | 熟女俱乐部五十路六十路av | 人妻互换免费中文字幕 | 日韩精品无码免费一区二区三区 | 久久精品无码一区二区三区 | 久久无码中文字幕免费影院蜜桃 | 男女性色大片免费网站 | 日韩av无码一区二区三区 | √天堂中文官网8在线 | 伊人久久大香线蕉午夜 | 精品厕所偷拍各类美女tp嘘嘘 | 国产欧美亚洲精品a | 无码av最新清无码专区吞精 | 中文无码伦av中文字幕 | 国产无遮挡吃胸膜奶免费看 | 国产真实伦对白全集 | 人妻少妇精品久久 | 亚洲性无码av中文字幕 | 一区二区传媒有限公司 | 久久综合给合久久狠狠狠97色 | 中文字幕人妻无码一区二区三区 | 色一情一乱一伦一区二区三欧美 | 亚洲一区二区三区国产精华液 | 鲁鲁鲁爽爽爽在线视频观看 | 国产亚av手机在线观看 | 天干天干啦夜天干天2017 | 日韩精品无码一本二本三本色 | 少妇一晚三次一区二区三区 | 伦伦影院午夜理论片 | 丁香啪啪综合成人亚洲 | 桃花色综合影院 | 国产乱人伦app精品久久 国产在线无码精品电影网 国产国产精品人在线视 | 久久久久亚洲精品男人的天堂 | 精品国产国产综合精品 | 在线观看欧美一区二区三区 | 国内精品人妻无码久久久影院蜜桃 | 中文字幕无码av波多野吉衣 | 又粗又大又硬又长又爽 | 99精品久久毛片a片 | 国产精品自产拍在线观看 | 清纯唯美经典一区二区 | 国产激情精品一区二区三区 | 国产精品无码一区二区桃花视频 | 亚洲男人av天堂午夜在 | 波多野结衣乳巨码无在线观看 | 波多野结衣aⅴ在线 | 好男人社区资源 | 精品久久8x国产免费观看 | 小泽玛莉亚一区二区视频在线 | 国精产品一区二区三区 | 国产婷婷色一区二区三区在线 | 日本熟妇乱子伦xxxx | 中文字幕人成乱码熟女app | 成人女人看片免费视频放人 | 国产精品无码久久av | 国产农村妇女aaaaa视频 撕开奶罩揉吮奶头视频 | 国产凸凹视频一区二区 | 久久久精品国产sm最大网站 | 免费无码午夜福利片69 | 久久人人爽人人人人片 | 国产精品久久久久久无码 | 97人妻精品一区二区三区 | 国产成人综合在线女婷五月99播放 | 中国女人内谢69xxxx | 国产又爽又猛又粗的视频a片 | 午夜不卡av免费 一本久久a久久精品vr综合 | 亚洲欧美综合区丁香五月小说 | 国产欧美精品一区二区三区 | 成人欧美一区二区三区黑人免费 | 丝袜 中出 制服 人妻 美腿 | 成年女人永久免费看片 | 久久精品中文闷骚内射 | 亚洲爆乳大丰满无码专区 | 亚洲中文字幕在线无码一区二区 | 色欲久久久天天天综合网精品 | 午夜精品久久久久久久 | аⅴ资源天堂资源库在线 | 精品一区二区三区无码免费视频 | 久久国内精品自在自线 | 东京一本一道一二三区 | 日韩亚洲欧美精品综合 | 欧美国产日韩亚洲中文 | 人人妻人人澡人人爽欧美精品 | 欧美激情一区二区三区成人 | 99国产欧美久久久精品 | 免费观看的无遮挡av | 美女极度色诱视频国产 | 宝宝好涨水快流出来免费视频 | 无码人妻丰满熟妇区五十路百度 | 少妇性l交大片欧洲热妇乱xxx | 日产国产精品亚洲系列 | 久久精品丝袜高跟鞋 | 国产激情综合五月久久 | 东京无码熟妇人妻av在线网址 | 人人超人人超碰超国产 | 久久人人爽人人爽人人片av高清 | 性色av无码免费一区二区三区 | 自拍偷自拍亚洲精品10p | 成人欧美一区二区三区黑人 | 亚洲无人区一区二区三区 | 免费看男女做好爽好硬视频 | 日韩精品无码一区二区中文字幕 | 玩弄少妇高潮ⅹxxxyw | 波多野结衣av一区二区全免费观看 | 18禁止看的免费污网站 | 中文字幕+乱码+中文字幕一区 | 欧美一区二区三区 | 中文字幕av日韩精品一区二区 | 婷婷丁香五月天综合东京热 | 中文毛片无遮挡高清免费 | 中文字幕无线码 | 成人片黄网站色大片免费观看 | 国产乱子伦视频在线播放 | 九九综合va免费看 | 无码福利日韩神码福利片 | 国产午夜视频在线观看 | 台湾无码一区二区 | 少妇的肉体aa片免费 | 亚洲自偷自拍另类第1页 | 亚洲日本va午夜在线电影 | 国产热a欧美热a在线视频 | 亚洲乱码中文字幕在线 | 无码精品国产va在线观看dvd | 午夜无码人妻av大片色欲 | 300部国产真实乱 | 久久97精品久久久久久久不卡 | 久久这里只有精品视频9 | 久久精品国产一区二区三区肥胖 | 色 综合 欧美 亚洲 国产 | 久青草影院在线观看国产 | 伊人色综合久久天天小片 | 欧美人与牲动交xxxx | 亚洲精品一区二区三区婷婷月 | 国产情侣作爱视频免费观看 | 久久久成人毛片无码 | 日日麻批免费40分钟无码 | 久久久精品人妻久久影视 | 亚洲色在线无码国产精品不卡 | 亚洲色欲色欲欲www在线 | 性色av无码免费一区二区三区 | 18禁止看的免费污网站 | 在线 国产 欧美 亚洲 天堂 | 免费观看激色视频网站 | 性欧美疯狂xxxxbbbb | 午夜福利试看120秒体验区 | 国产精品亚洲综合色区韩国 | 亚洲国产av精品一区二区蜜芽 | 欧美大屁股xxxxhd黑色 | 亚洲精品午夜无码电影网 | 亚洲欧美日韩国产精品一区二区 | 粉嫩少妇内射浓精videos | 欧美丰满熟妇xxxx性ppx人交 | 亚洲一区二区三区在线观看网站 | 国产三级久久久精品麻豆三级 | 未满成年国产在线观看 | 国产无遮挡吃胸膜奶免费看 | 国产精品香蕉在线观看 | 国产精品手机免费 | 日欧一片内射va在线影院 | 精品国产一区二区三区av 性色 | 国产偷自视频区视频 | 亚洲欧美色中文字幕在线 | 老熟女乱子伦 | 性史性农村dvd毛片 | 无码人妻少妇伦在线电影 | 无码人妻丰满熟妇区五十路百度 | 欧美猛少妇色xxxxx | а√资源新版在线天堂 | 国产一区二区三区四区五区加勒比 | 狠狠cao日日穞夜夜穞av | 日本精品人妻无码77777 天堂一区人妻无码 | av人摸人人人澡人人超碰下载 | 久久久久成人精品免费播放动漫 | 国产一区二区三区日韩精品 | 99久久久无码国产aaa精品 | 国产精品无码久久av | 无码人妻少妇伦在线电影 | 欧美丰满熟妇xxxx性ppx人交 | 日韩av无码中文无码电影 | 丰满少妇高潮惨叫视频 | 好男人www社区 | 亚洲欧美色中文字幕在线 | 正在播放老肥熟妇露脸 | 欧美阿v高清资源不卡在线播放 | 在线a亚洲视频播放在线观看 | 狠狠亚洲超碰狼人久久 | 2020久久超碰国产精品最新 | 欧美激情内射喷水高潮 | 熟妇人妻激情偷爽文 | 奇米影视888欧美在线观看 | 人人妻人人澡人人爽欧美一区九九 | 亚洲 日韩 欧美 成人 在线观看 | 蜜桃av蜜臀av色欲av麻 999久久久国产精品消防器材 | 日本熟妇人妻xxxxx人hd | 青青草原综合久久大伊人精品 | 久久久久亚洲精品中文字幕 | 久久五月精品中文字幕 | 中文字幕无线码 | 爆乳一区二区三区无码 | 亚洲色大成网站www | 亚洲s码欧洲m码国产av | 欧美亚洲国产一区二区三区 | 国产精品久久国产精品99 | 东京热无码av男人的天堂 | 免费无码av一区二区 | 午夜福利不卡在线视频 | 国产精品永久免费视频 | 久久五月精品中文字幕 | 亚洲日韩中文字幕在线播放 | 国产偷自视频区视频 | 天堂无码人妻精品一区二区三区 | 国产疯狂伦交大片 | 中文字幕无码日韩欧毛 | 正在播放东北夫妻内射 | 思思久久99热只有频精品66 | 亚洲精品综合一区二区三区在线 | 欧美兽交xxxx×视频 | 亚洲精品成人福利网站 | 天天摸天天碰天天添 | 波多野结衣av一区二区全免费观看 | 久在线观看福利视频 | 天堂亚洲免费视频 | 一本色道婷婷久久欧美 | 亚洲中文字幕va福利 | 丰满少妇高潮惨叫视频 | 色爱情人网站 | 九九热爱视频精品 | 欧美老妇与禽交 | 国产人妖乱国产精品人妖 | 免费看男女做好爽好硬视频 | 亚洲国产欧美日韩精品一区二区三区 | 无码精品国产va在线观看dvd | 国产舌乚八伦偷品w中 | 久久久亚洲欧洲日产国码αv | 中文无码精品a∨在线观看不卡 | 日本又色又爽又黄的a片18禁 | 亚洲区小说区激情区图片区 | 又黄又爽又色的视频 | 亚洲成a人一区二区三区 | 久激情内射婷内射蜜桃人妖 | 久久久久久九九精品久 | 国产亚洲精品久久久闺蜜 | 亚洲国产成人a精品不卡在线 | 亚洲成熟女人毛毛耸耸多 | 国产精品久久久久无码av色戒 | 天天躁日日躁狠狠躁免费麻豆 | 国产97在线 | 亚洲 | 久久久久av无码免费网 | 亚洲欧美综合区丁香五月小说 | 中文字幕无码人妻少妇免费 | 18禁黄网站男男禁片免费观看 | 99久久久国产精品无码免费 | 国产极品美女高潮无套在线观看 | 无码人妻久久一区二区三区不卡 | 日本一本二本三区免费 | 久久综合香蕉国产蜜臀av | 亚洲国产一区二区三区在线观看 | 国产亚洲精品久久久闺蜜 | 色偷偷人人澡人人爽人人模 | 日本精品久久久久中文字幕 | 精品国产青草久久久久福利 | 人妻少妇被猛烈进入中文字幕 | 狂野欧美性猛xxxx乱大交 | 久久久精品国产sm最大网站 | 免费看少妇作爱视频 | 在线观看欧美一区二区三区 | 亚洲成av人在线观看网址 | 成年美女黄网站色大免费视频 | 免费无码肉片在线观看 | 欧美精品在线观看 | 牲欲强的熟妇农村老妇女视频 | 67194成是人免费无码 | 亚无码乱人伦一区二区 | 欧美freesex黑人又粗又大 | 亚洲国产精品久久久久久 | 精品久久久无码中文字幕 | 久久伊人色av天堂九九小黄鸭 | 国产成人无码av在线影院 | 国产一精品一av一免费 | 少妇被黑人到高潮喷出白浆 | 免费播放一区二区三区 | 亚洲自偷自拍另类第1页 | 国产精品-区区久久久狼 | 国产在线一区二区三区四区五区 | 国产偷抇久久精品a片69 | 欧美人与动性行为视频 | 亚洲国产精品成人久久蜜臀 | 久9re热视频这里只有精品 | 国产九九九九九九九a片 | 国产精品亚洲专区无码不卡 | 久久精品中文字幕大胸 | 免费无码一区二区三区蜜桃大 | 国产精品资源一区二区 | 色一情一乱一伦一区二区三欧美 | 2020最新国产自产精品 | 国产人妖乱国产精品人妖 | 国产人成高清在线视频99最全资源 | 日韩亚洲欧美精品综合 | 天堂亚洲免费视频 | 99久久无码一区人妻 | 亚洲精品午夜无码电影网 | 又大又硬又黄的免费视频 |