日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Beej网络编程指南《三》

發布時間:2025/3/15 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Beej网络编程指南《三》 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

9手冊

在Unix世界里,有很多手冊。它們有小部分描述了你可以使用的單個函數。

當然,手動的東西太難打了。我的意思是,在Unix世界里,沒有人,包括我自己,喜歡打那么多。事實上,我可以長篇大論地說我有多喜歡簡潔,但我會簡潔,不會用冗長的抨擊來煩擾你,說我幾乎在所有情況下都非常喜歡簡潔。

[掌聲]

謝謝。我要說的是,這些頁面在Unix世界中被稱為“手冊頁”,為了讓你閱讀愉快,我在這里包含了我自己的截斷變體。問題是,這些函數中的許多比我所說的更通用,但我將只介紹與互聯網套接字編程相關的部分。

但是等等!這不是我男人頁面的全部問題:

  • 它們不完整,只顯示了指南中的基礎知識。

  • 現實世界中有比這更多的人文頁面。

  • 它們與您系統上的不同。

  • 對于系統上的某些功能,頭文件可能不同。

  • 對于系統上的某些函數,函數參數可能不同。

如果你想了解真正的信息,可以在本地的Unix手冊頁面上輸入man any,其中的“不管”是你非常感興趣的東西,比如“接受”。(我肯定微軟Visual Studio在他們的幫助部分也有類似的東西。但是“人”更好,因為它比“幫助”簡潔一個字節。Unix又贏了!)

那么,如果這些有如此大的缺陷,為什么還要在指南中包含它們呢?嗯,有幾個原因,但最好的是(a)這些版本是專門面向網絡編程的,比真正的版本更容易消化,(b)這些版本包含示例!

哦!說到這些例子,我不傾向于插入所有的錯誤檢查,因為它確實增加了代碼的長度。但是你絕對應該在你進行任何系統調用的時候進行錯誤檢查,除非你完全100%確定它不會失敗,你甚至應該這樣做!

9.1接受()

在偵聽套接字上接受傳入連接

9.1.0.1簡介

#include <sys/types.h>#include <sys/socket.h>int accept(int s, struct sockaddr *addr, socklen_t *addrlen);

9.1.0.2說明

一旦您經歷了獲取SOCK_STREAM套接字并用listk()為傳入連接設置它的麻煩,那么您將調用接受()來實際獲取一個新的套接字描述符,用于與新連接的客戶端的后續通信。

您用于監聽的舊套接字仍然存在,并且將在它們進來時用于進一步接受()調用。

ParameterDescriptionsThe listen()ing socket descriptor.addrThis is filled in with the address of the site that’s connecting to you.addrlenThis is filled in with the sizeof() the structure returned in the addr parameter. You can safely ignore it if you assume you’re getting a struct sockaddr_in back, which you know you are, because that’s the type you passed in for addr.

接受()通常會阻塞,您可以使用選擇()提前查看偵聽套接字描述符是否“準備好讀取”。如果是,那么有一個新的連接等待接受()編輯!耶。或者,您可以使用fcntl()在偵聽套接字上設置O_NONBLOCK標志,然后它永遠不會阻塞,而是選擇返回-1,并將errno設置為EWOULDBLOCK。

接受()返回的套接字描述符是一個真正的套接字描述符,打開并連接到遠程主機。完成后必須關閉()。

9.1.0.3返回值

接受()返回新連接的套接字描述符,或-1開錯誤,并適當設置errno。

9.1.0.4實例

struct sockaddr_storage their_addr; socklen_t addr_size; struct addrinfo hints, *res; int sockfd, new_fd;// first, load up address structs with getaddrinfo():memset(&hints, 0, sizeof hints); hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE; // fill in my IP for megetaddrinfo(NULL, MYPORT, &hints, &res);// make a socket, bind it, and listen on it:sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); bind(sockfd, res->ai_addr, res->ai_addrlen); listen(sockfd, BACKLOG);// now accept an incoming connection:addr_size = sizeof their_addr; new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &addr_size);// ready to communicate on socket descriptor new_fd!

9.1.0.5也看

套接字``(),getaddrinfo(),``聽()``,``結構sockaddr_in

9.2綁定()

將套接字與IP地址和端口號關聯起來

9.2.0.1簡介

#include <sys/types.h>#include <sys/socket.h>int bind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen);

9.2.0.2描述

當遠程計算機想要連接到您的服務器程序時,它需要兩條信息:IP地址和端口號。bind()調用允許您這樣做。

首先,我們調用getaddrinfo()來加載一個帶有目標地址和端口信息的結構Sockaddr。然后我們調用套接字()來獲取一個套接字描述符,然后將套接字和地址傳遞給bind(),然后IP地址和端口神奇地(使用實際的魔法)綁定到套接字上!

如果您不知道您的IP地址,或者您知道您在機器上只有一個IP地址,或者您不關心使用了哪個機器的IP地址,您可以簡單地將hint參數中的AI_PASSIVE標志傳遞給getaddrinfo()。這樣做的目的是用一個特殊的值填入結構體sokaddr的IP地址部分,該值告訴bind()它應該自動填入主機的IP地址。

什么是什么?是什么特殊值被加載到struct sokaddr的IP地址,導致它自動填充地址與當前主機?我會告訴你,但請記住,這是只有當你填寫的結構sokaddr手工;如果不是,使用getaddrinfo()的結果,如上所述。在IPv4中,sin_addr。s_addr結構sockaddr_in結構的字段被設置為INADDR_ANY。在IPv6中,結構sockaddr_in6結構的sin6_addr字段被分配到從全局變量in6addr_any。或者,如果要in6_addr聲明一個新結構,可以將其初始化為IN6ADDR_ANY_INIT。

最后,addrlen參數應該設置為sizeofmy_addr。

9.2.0.3返回值

成功時返回零,錯誤時返回-1(errno將相應地設置)。

9.2.0.4實例

// modern way of doing things with getaddrinfo()struct addrinfo hints, *res; int sockfd;// first, load up address structs with getaddrinfo():memset(&hints, 0, sizeof hints); hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE; // fill in my IP for megetaddrinfo(NULL, "3490", &hints, &res);// make a socket: // (you should actually walk the "res" linked list and error-check!)sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);// bind it to the port we passed in to getaddrinfo():bind(sockfd, res->ai_addr, res->ai_addrlen); // example of packing a struct by hand, IPv4struct sockaddr_in myaddr; int s;myaddr.sin_family = AF_INET; myaddr.sin_port = htons(3490);// you can specify an IP address: inet_pton(AF_INET, "63.161.169.137", &(myaddr.sin_addr));// or you can let it automatically select one: myaddr.sin_addr.s_addr = INADDR_ANY;s = socket(PF_INET, SOCK_STREAM, 0); bind(s, (struct sockaddr*)&myaddr, sizeof myaddr);

9.2.0.5也看

getaddrinfo(),套接字``(),結構sockaddr_in,結構in_addr

9.3連接()

將套接字連接到服務器

9.3.0.1簡介

#include <sys/types.h>#include <sys/socket.h>int connect(int sockfd, const struct sockaddr *serv_addr,socklen_t addrlen);

9.3.0.2說明

一旦您已經建立了一個套接字描述符與套接字()調用,您可以連接()該套接字到遠程服務器使用良好命名的連接()系統調用。所有您需要做的是傳遞套接字描述符和服務器的地址,你有興趣更好地了解。(哦,還有地址的長度,這通常是傳遞給這樣的函數。)

通常,這些信息是調用getaddrinfo()的結果,但是如果你愿意,你可以填寫你自己的結構。

如果您還沒有在套接字描述符上調用bind(),它會自動綁定到您的IP地址和一個隨機的本地端口。如果您不是服務器,這通常很好,因為您真的不在乎您的本地端口是什么;你只關心遠程端口是什么,所以你可以把它放在serv_addr參數中。如果您真的希望您的客戶端套接字位于特定的IP地址和端口上,您可以調用bind(),但這種情況非常罕見。

一旦套接字被連接(),你就可以自由地發送()和recv()數據。

特別注意:如果您連接()一個SOCK_DGRAMUDP套接字到一個遠程主機,您可以使用mail()和recv()以及sendto()和recvfrom()。如果您愿意的話。

9.3.0.3返回值

成功時返回零,錯誤時返回-1(errno將相應地設置)。

9.3.0.4例子

// connect to www.example.com port 80 (http)struct addrinfo hints, *res; int sockfd;// first, load up address structs with getaddrinfo():memset(&hints, 0, sizeof hints); hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever hints.ai_socktype = SOCK_STREAM;// we could put "80" instead on "http" on the next line: getaddrinfo("www.example.com", "http", &hints, &res);// make a socket:sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);// connect it to the address and port we passed in to getaddrinfo():connect(sockfd, res->ai_addr, res->ai_addrlen);

9.3.0.5另見

套接字`(),`綁定()

9.4關閉()

關閉套接字描述符

9.4.0.1簡介

#include <unistd.h>int close(int s);

9.4.0.2描述

在您完成了使用套接字的任何瘋狂的計劃,你已經編造,你不想發送()或recv()或,事實上,做任何其他與套接字,你可以關閉()它,它將被釋放,永遠不會再使用。

如果遠程端調用recv(),它將返回0;如果遠程端調用了mail(),它將接收到一個信號SIGPIPE,而mail()將返回-1,errno將被設置為EPIPE。

Windows用戶:你需要使用的函數叫做關閉(),而不是關閉()。如果你試圖在套接字描述符上使用關閉(),Windows可能會生氣…你不喜歡它生氣的時候。

9.4.0.3返回值

成功時返回零,錯誤時返回-1(errno將相應地設置)。

9.4.0.4例子

s = socket(PF_INET, SOCK_DGRAM, 0); . . . // a whole lotta stuff...*BRRRONNNN!* . . . close(s); // not much to it, really.

9.4.0.5查看

套接字`(),`關機()

9.5 getaddrinfo(),freaddrinfo(),gai_strerror()

獲取有關主機名和/或服務的信息,并加載一個帶有結果的結構sokaddr。

9.5.0.1簡介

#include <sys/types.h> #include <sys/socket.h> #include <netdb.h> int getaddrinfo(const char *nodename, const char *servname, const struct addrinfo *hints, struct addrinfo **res); void freeaddrinfo(struct addrinfo *ai); const char *gai_strerror(int ecode); struct addrinfo { int ai_flags; // AI_PASSIVE, AI_CANONNAME, ... int ai_family; // AF_xxx int ai_socktype; // SOCK_xxx int ai_protocol; // 0 (auto) or IPPROTO_TCP, IPPROTO_UDP socklen_t ai_addrlen; // length of ai_addr char *ai_canonname; // canonical name for nodename struct sockaddr *ai_addr; // binary address struct addrinfo *ai_next; // next structure in linked list };

9.5.0.2描述

getaddrinfo()是一個非常好的函數,它可以返回特定主機名的信息(比如它的IP地址),并為您加載一個構建的Sockaddr,處理一些細節(比如它是IPv4還是IPv6)。它取代了舊的函數gethstatbyname()和getservbyname()。下面的描述包含了很多可能有點令人生畏的信息,但是實際使用非常簡單。首先看看這些例子可能是值得的。

您感興趣的主機名位于nodename參數中。地址可以是主機名,如“www.example.com”,也可以是IPv4或IPv6地址(作為字符串傳遞)。如果您使用AI_PASSIVE標志,該參數也可以為NULL(見下文)。

servname參數基本上是端口號。它可以是端口號(作為字符串傳遞,如“80”),也可以是服務名稱,如“超文本傳輸協議”或“tftp”或“smtp”或“pop”等。眾所周知的服務名稱可以在IANA端口列表48或您的 /etc/services文件中找到。

最后,對于輸入參數,我們有一些提示。這是您真正定義getaddrinfo()函數要做什么的地方。在使用memset()之前,將整個結構歸零。讓我們看看在使用前需要設置的字段。

ai_flags可以設置為多種內容,但這里有幾個重要的內容。(可以通過與|運算符一起按位ORing來指定多個標志)。查看手冊頁面以獲取完整的標志列表。

AI_CANONNAME將結果的ai_canonname填充為主機的規范(真實)名稱。AI_PASSIVE將結果的IP地址填充為INADDR_ANY(IPv4)或in6addr_any(IPv6);這將導致后續調用bind(),以用當前主機的地址自動填充struct solkaddr的IP地址。當您不想對地址進行硬編碼時,這非常適合設置服務器。

如果您使用AI_PASSIVE,標志,那么您可以在節點名稱中傳遞NULL(因為bind()稍后會為您填寫)。

繼續輸入參數,您可能需要將ai_family設置為AF_UNSPEC,這告訴getaddrinfo()查找IPv4和IPv6地址。您也可以通過AF_INET或AF_INET6將自己限制在其中一個。

接下來,ocktype字段應該設置為SOCK_STREAM或SOCK_DGRAM,這取決于您想要哪種類型的套接字。

最后,只需將ai_protocol保持在0即可自動選擇協議類型。

現在,在你把所有的東西都放進去之后,你終于可以打電話給getaddrinfo()了!

當然,這就是樂趣的開始。res現在將指向一個結構地址的鏈接列表,您可以通過這個列表獲得所有與您傳遞的提示相匹配的地址。

現在,有可能得到一些地址因為這樣或那樣的原因而不起作用,所以Linux手冊頁所做的就是循環遍歷列表,調用套接字()和連接()(或者綁定(),如果您正在設置帶有AI_PASSIVE標志的服務器),直到它成功。

最后,當你完成了鏈接列表,你需要調用freaddrinfo()來釋放內存(否則它會泄露,有些人會不高興)。

9.5.0.3返回值

成功時返回零,錯誤時返回非零。如果返回非零,您可以使用函數gai_strerror()在返回值中獲取錯誤代碼的可打印版本。

9.5.0.4實例

// code for a client connecting to a server // namely a stream socket to www.example.com on port 80 (http) // either IPv4 or IPv6int sockfd; struct addrinfo hints, *servinfo, *p; int rv;memset(&hints, 0, sizeof hints); hints.ai_family = AF_UNSPEC; // use AF_INET6 to force IPv6 hints.ai_socktype = SOCK_STREAM;if ((rv = getaddrinfo("www.example.com", "http", &hints, &servinfo)) != 0) {fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));exit(1); }// loop through all the results and connect to the first we can for(p = servinfo; p != NULL; p = p->ai_next) {if ((sockfd = socket(p->ai_family, p->ai_socktype,p->ai_protocol)) == -1) {perror("socket");continue;}if (connect(sockfd, p->ai_addr, p->ai_addrlen) == -1) {perror("connect");close(sockfd);continue;}break; // if we get here, we must have connected successfully }if (p == NULL) {// looped off the end of the list with no connectionfprintf(stderr, "failed to connect\n");exit(2); }freeaddrinfo(servinfo); // all done with this structure // code for a server waiting for connections // namely a stream socket on port 3490, on this host's IP // either IPv4 or IPv6.int sockfd; struct addrinfo hints, *servinfo, *p; int rv;memset(&hints, 0, sizeof hints); hints.ai_family = AF_UNSPEC; // use AF_INET6 to force IPv6 hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE; // use my IP addressif ((rv = getaddrinfo(NULL, "3490", &hints, &servinfo)) != 0) {fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));exit(1); }// loop through all the results and bind to the first we can for(p = servinfo; p != NULL; p = p->ai_next) {if ((sockfd = socket(p->ai_family, p->ai_socktype,p->ai_protocol)) == -1) {perror("socket");continue;}if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) {close(sockfd);perror("bind");continue;}break; // if we get here, we must have connected successfully }if (p == NULL) {// looped off the end of the list with no successful bindfprintf(stderr, "failed to bind socket\n");exit(2); }freeaddrinfo(servinfo); // all done with this structure

9.5.0.5也看

#####################################################################################``#########

9.6地名()

返回系統的名稱

9.6.0.1簡介

#include <sys/unistd.h> int gethostname(char *name, size_t len);

9.6.0.2說明

你的系統有一個名字。他們都有。這是一個比我們談論的其他網絡東西稍微更Unixy的東西,但是它仍然有它的用途。

例如,您可以獲取您的主機名,然后調用gethostbyname()來查找您的IP地址。

參數name應該指向一個將保存主機名的緩沖區,len是該緩沖區的大小(以字節為單位)。gethostname()不會覆蓋緩沖區的結尾(它可能會返回錯誤,或者它可能會停止寫入),如果緩沖區中有空間,它將NUL終止字符串。

9.6.0.3返回值

成功時返回零,錯誤時返回-1(errno將相應地設置)。

9.6.0.4例子

char hostname[128];gethostname(hostname, sizeof hostname);printf("My hostname: %s\n", hostname);

9.6.0.5另見

地名()

9.7 gethokbyname(), gethokbyaddr()

獲取主機名的IP地址,反之亦然

9.7.0.1簡介

#include <sys/socket.h> #include <netdb.h> struct hostent *gethostbyname(const char *name); // DEPRECATED! struct hostent *gethostbyaddr(const char *addr, int len, int type);

9.7.0.2描述

請注意:這兩個函數被*getaddrinfo()和getnameinfo()所取代!特別是,gethostby*name()不能很好地與IPv6一起工作。

這些函數在主機名和IP地址之間來回映射。例如,如果您有www.example.com,您可以使用gethostbyname()獲取其IP地址并將其存儲在結構in_addr中。

相反,如果你有一個結構in_addr或結構in6_addr,你可以使用gethstatbyaddr()來獲取主機名。gethstatbyaddr()與IPv6兼容,但``*是*``你應該使用更新的getnameinfo()來代替。

(如果你有一個包含點和數字格式的IP地址的字符串,你想查找的主機名,你最好使用帶有AI_CANONNAME標志的getaddrinfo()。)

gethstatbyname()接受一個類似www.yahoo.com的字符串,并返回一個包含大量信息的結構宿主,包括IP地址。(其他信息是官方主機名、別名列表、地址類型、地址長度和地址列表——這是一個通用結構,一旦你看到了如何使用,就很容易用于我們的特定目的。)

gethstatbyaddr()接受一個結構in_addr或結構in6_addr并帶給你一個相應的主機名(如果有的話),所以它有點像gethstatbyname()的相反。至于參數,即使addr是一個char*,你實際上想要傳遞一個指向結構in_addr的指針。len應該是sizeof(結構in_addr),類型應該是AF_INET。

那么返回的這個結構宿主是什么呢?它有許多字段包含有關所討論宿主的信息。

FieldDescriptionchar h_nameThe real canonical host name.char **h_aliasesA list of aliases that can be accessed with arrays—the last element is NULLint h_addrtypeThe result’s address type, which really should be AF_INET for our purposes.int lengthThe length of the addresses in bytes, which is 4 for IP (version 4) addresses.char h_addr_listA list of IP addresses for this host. Although this is a char, it’s really an array of struct in_addrs in disguise. The last array element is NULL.h_addrA commonly defined alias for h_addr_list[0]. If you just want any old IP address for this host (yeah, they can have more than one) just use this field.

9.7.0.3返回值

成功時返回指向結果結構宿主的指針,錯誤時返回NULL。

這些函數不是通常的perror()和所有通常用于錯誤報告的東西,而是在變量h_errno中具有并行結果,可以使用函數herror()或hstrirror()打印。這些函數的工作原理就像您習慣的經典errno、perror()和strarror()函數一樣。

9.7.0.4例子

// THIS IS A DEPRECATED METHOD OF GETTING HOST NAMES // use getaddrinfo() instead!#include <stdio.h> #include <errno.h> #include <netdb.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h>int main(int argc, char *argv[]) {int i;struct hostent *he;struct in_addr **addr_list;if (argc != 2) {fprintf(stderr,"usage: ghbn hostname\n");return 1;}if ((he = gethostbyname(argv[1])) == NULL) { // get the host infoherror("gethostbyname");return 2;}// print information about this host:printf("Official name is: %s\n", he->h_name);printf(" IP addresses: ");addr_list = (struct in_addr **)he->h_addr_list;for(i = 0; addr_list[i] != NULL; i++) {printf("%s ", inet_ntoa(*addr_list[i]));}printf("\n");return 0; } // THIS HAS BEEN SUPERCEDED // use getnameinfo() instead!struct hostent *he; struct in_addr ipv4addr; struct in6_addr ipv6addr;inet_pton(AF_INET, "192.0.2.34", &ipv4addr); he = gethostbyaddr(&ipv4addr, sizeof ipv4addr, AF_INET); printf("Host name: %s\n", he->h_name);inet_pton(AF_INET6, "2001:db8:63b3:1::beef", &ipv6addr); he = gethostbyaddr(&ipv6addr, sizeof ipv6addr, AF_INET6); printf("Host name: %s\n", he->h_name);

9.7.0.5另見

getaddrinfo``(),getnameinfo``(),gethstatname``(),``errno,perror(),``strrror()``,``結構``in_addr

9.8 getnameinfo()

查找給定結構體ockaddr的主機名和服務名信息。

9.8.0.1簡介

#include <sys/socket.h>#include <netdb.h>int getnameinfo(const struct sockaddr *sa, socklen_t salen,char *host, size_t hostlen,char *serv, size_t servlen, int flags);

9.8.0.2描述

這個函數與getaddrinfo()相反,也就是說,這個函數接受一個已經加載的結構sokaddr,并對其進行名稱和服務名稱查找。它取代了舊的gethostbyaddr()和getservbyport()函數。

您必須在sa參數中傳遞一個指向struct solkaddr的指針(實際上可能是一個結構sockaddr_in或您已經轉換的結構sockaddr_in6),以及salen中該結構的長度。

生成的主機名和服務名將被寫入主機和服務器參數指向的區域。當然,您必須在host len和servlen中指定這些緩沖區的最大長度。

最后,有幾個標志可以傳遞,但這里有幾個好的標志。NI_NOFQDN將導致主機只包含主機名,而不是整個域名。如果在DNS查找中找不到名稱,NI_NAMEREQD將導致函數失敗(如果不指定此標志并且找不到名稱,getnameinfo()將在主機中放置IP地址的字符串版本)。

像往常一樣,查看您當地的手冊頁面以獲取完整的獨家新聞。

9.8.0.3返回值

成功時返回零,錯誤時返回非零。如果返回值為非零,則可以將其傳遞給gai_strerror()以獲得人類可讀的字符串。有關更多信息,請參閱getaddrinfo。

9.8.0.4例子

struct sockaddr_in6 sa; // could be IPv4 if you want char host[1024]; char service[20];// pretend sa is full of good information about the host and port...getnameinfo(&sa, sizeof sa, host, sizeof host, service, sizeof service, 0);printf(" host: %s\n", host); // e.g. "www.example.com" printf("service: %s\n", service); // e.g. "http"

9.8.0.5另見

Getaddrinfo(),gethokbyaddr(``)

9.9 getpeername()

返回連接遠程端的地址信息

9.9.0.1簡介

#include <sys/socket.h>int getpeername(int s, struct sockaddr *addr, socklen_t *len);

9.9.0.2說明

一旦你接受了一個遠程連接,或者連接了一個服務器,你現在就有了一個所謂的對等點。你的對等點就是你連接的計算機,由一個IP地址和一個端口來識別。所以…

getpeername()簡單地返回一個結構sockaddr_in填充有關連接到的機器的信息。

為什么它被稱為“名稱”?嗯,有很多不同類型的套接字,不僅僅是像我們在本指南中使用的互聯網套接字,所以“名稱”是一個很好的通用術語,涵蓋了所有情況。然而,在我們的例子中,對等方的“名稱”是它的IP地址和端口。

雖然該函數返回len中結果地址的大小,但您必須用addr的大小預加載len。

9.9.0.3返回值

成功時返回零,錯誤時返回-1(errno將相應地設置)。

9.9.0.4實例

// assume s is a connected socketsocklen_t len;struct sockaddr_storage addr;char ipstr[INET6_ADDRSTRLEN];int port;len = sizeof addr;getpeername(s, (struct sockaddr*)&addr, &len);// deal with both IPv4 and IPv6:if (addr.ss_family == AF_INET) { struct sockaddr_in *s = (struct sockaddr_in *)&addr; port = ntohs(s->sin_port); inet_ntop(AF_INET, &s->sin_addr, ipstr, sizeof ipstr);} else { // AF_INET6 struct sockaddr_in6 *s = (struct sockaddr_in6 *)&addr; port = ntohs(s->sin6_port); inet_ntop(AF_INET6, &s->sin6_addr, ipstr, sizeof ipstr);}printf("Peer IP address: %s\n", ipstr);printf("Peer port : %d\n", port);

9.9.0.5也看

gethokbyname``()``, gethokbyname(), gethokbyaddr()

9.10errno

保存上次系統調用的錯誤代碼

9.10.0.1簡介

#include <errno.h> int errno;

9.10.0.2描述

這個變量保存了許多系統調用的錯誤信息。如果你記得的話,像套接字()和監聽()這樣的東西在錯誤時返回-1,它們設置errno的確切值來讓你知道具體發生了哪個錯誤。

頭文件errno. h列出了一堆錯誤的常量符號名稱,如EADDRINUSE、EPIPE、ECONNREFUSED等。您的本地手冊頁面將告訴您哪些代碼可以作為錯誤返回,您可以在運行時使用這些代碼以不同的方式處理不同的錯誤。

或者,更常見的是,您可以調用perror()或strirror()來獲取該錯誤的可讀版本。

對于多線程愛好者來說,有一點需要注意的是,在大多數系統中errno是以線程安全的方式定義的。(也就是說,它實際上不是一個全局變量,但它的行為就像單線程環境中的全局變量一樣。)

9.10.0.3返回值

變量的值是最近發生的錯誤,如果最后一個操作成功,這可能是“成功”的代碼。

9.10.0.4例子

s = socket(PF_INET, SOCK_STREAM, 0); if (s == -1) {perror("socket"); // or use strerror() }tryagain: if (select(n, &readfds, NULL, NULL) == -1) {// an error has occurred!!// if we were only interrupted, just restart the select() call:if (errno == EINTR) goto tryagain; // AAAA! goto!!!// otherwise it's a more serious error:perror("select");exit(1); }

9.10.0.5另見

錯誤的``選擇

9.11 fcntl()

控制套接字描述符

9.11.0.1簡介

#include <sys/unistd.h>#include <sys/fcntl.h>int fcntl(int s, int cmd, long arg);

9.11.0.2說明

此函數通常用于執行文件鎖定和其他面向文件的操作,但它也有一些與套接字相關的函數,您可能會不時看到或使用這些函數。

參數s是您希望操作的套接字描述符,cmd應該設置為F_SETFL,arg可以是以下命令之一。(就像我說的,fcntl()比我在這里說的要多,但我試圖保持面向套接字。)

cmdDescriptionO_NONBLOCKSet the socket to be non-blocking. See the section on blocking for more details.O_ASYNCSet the socket to do asynchronous I/O. When data is ready to be recv()’d on the socket, the signal SIGIO will be raised. This is rare to see, and beyond the scope of the guide. And I think it’s only available on certain systems.

9.11.0.3返回值

成功時返回零,錯誤時返回-1(errno將相應地設置)。

fcntl()系統調用的不同用法實際上有不同的返回值,但我在這里沒有討論它們,因為它們與套接字無關。有關更多信息,請參閱本地fcntl()手冊頁。

9.11.0.4實例

int s = socket(PF_INET, SOCK_STREAM, 0);fcntl(s, F_SETFL, O_NONBLOCK); // set to non-blockingfcntl(s, F_SETFL, O_ASYNC); // set to asynchronous I/O

9.11.0.5也看

阻塞,發送()

9.12 hton(), htonl(), ntohs(), ntohl()

將多字節整數類型從主機字節順序轉換為網絡字節順序

9.12.0.1簡介

#include <netinet/in.h> uint32_t htonl(uint32_t hostlong); uint16_t htons(uint16_t hostshort); uint32_t ntohl(uint32_t netlong); uint16_t ntohs(uint16_t netshort);

9.12.0.2描述

只是讓你不高興的是,不同的計算機在內部對它們的多字節整數(即任何大于char的整數)使用不同的字節順序。結果是,如果你從英特爾盒子向蘋果電腦發送()一個兩字節的短int(在它們變成英特爾盒子之前,我的意思是),一臺電腦認為是數字1,另一臺電腦認為是數字256,反之亦然。

解決這個問題的方法是,每個人都把分歧放在一邊,同意摩托羅拉和IBM是對的,而英特爾是以奇怪的方式做到的,所以我們都在發送字節順序之前將其轉換為“大端”。由于英特爾是一臺“小端”機器,將我們首選的字節順序稱為“網絡字節順序”在政治上要正確得多。所以這些函數從你的本機字節順序轉換為網絡字節順序,然后再轉換回來。

(這意味著在英特爾上,這些函數交換周圍的所有字節,而在PowerPC上,它們什么也不做,因為字節已經處于網絡字節順序。但是無論如何,你應該在你的代碼中始終使用它們,因為有人可能想在英特爾機器上構建它,并且仍然讓事情正常工作。)

請注意,所涉及的類型是32位(4字節,可能是int)和16位(2字節,很可能是短)數字。64位機器可能有一個用于64位int的htonll(),但我沒有見過它。你只需要寫你自己的。

不管怎樣,這些函數的工作方式是,您首先決定是從主機(您的機器)字節順序還是從網絡字節順序轉換。如果是“主機”,您要調用的函數的第一個字母是“h”。否則是“網絡”的“n”。函數名稱的中間總是“to”,因為您正在從一個“轉換”到“另一個”,倒數第二個字母顯示您正在轉換的內容。最后一個字母是數據的大小,短的“s”,長的“l”。因此:

FunctionDescriptionhtons()host to network shorthtonl()host to network longntohs()network to host shortntohl()network to host long

9.12.0.3返回值

每個函數返回轉換后的值。

9.12.0.4實例

uint32_t some_long = 10;uint16_t some_short = 20;uint32_t network_byte_order;// convert and sendnetwork_byte_order = htonl(some_long);send(s, &network_byte_order, sizeof(uint32_t), 0);some_short == ntohs(htons(some_short)); // this expression is true

9.13inet_ntoa()、inet_aton()、inet_addr

將IP地址從點和數字字符串轉換為結構in_addr

9.13.0.1簡介

#include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> // ALL THESE ARE DEPRECATED! Use inet_pton() or inet_ntop() instead!! char *inet_ntoa(struct in_addr in); int inet_aton(const char *cp, struct in_addr *inp); in_addr_t inet_addr(const char *cp);

9.13.0.2描述

這些函數不建議使用,因為它們不處理IPv6!使用*inet_ntop()*或*inet_pton()*代替!它們包含在這里是因為它們仍然可以在野外找到。

所有這些函數都從結構in_addr(最有可能是結構sockaddr_in的一部分)轉換成點和數字格式的字符串(例如“192.168.5.10”),反之亦然。如果你有一個在命令行上傳遞的IP地址,這是獲得一個結構in_addr連接()或其他什么的最簡單方法。如果你需要更多的權力,嘗試一些DNS函數,比如gethostbyname()或者在你的本地國家嘗試一次政變。

函數inet_ntoa()將結構in_addr中的網絡地址轉換為點和數字格式的字符串。“ntoa”中的“n”代表網絡,“a”代表ASCII,這是因為歷史原因(所以它是“網絡到ASCII”——“toa”后綴在C庫中有一個類似的朋友,叫做atoi(),它將ASCII字符串轉換為整數)。

函數inet_aton()是相反的,從點和數字字符串轉換成in_addr_t(這是s_addr結構in_addr的字段類型)。

最后,函數inet_addr()是一個較舊的函數,它的功能基本上與inet_aton()相同。理論上它是不建議使用的,但是你會經常看到它,如果你使用它,警察不會來找你。

9.13.0.3返回值

inet_aton()如果地址是有效的,則返回非零;如果地址無效,則返回零。

inet_ntoa()返回靜態緩沖區中的點和數字字符串,該字符串在每次調用函數時被覆蓋。

inet_addr()將地址作為in_addr_t返回,如果有錯誤,則返回-1。(這與試圖將字符串255.255.255.255轉換為有效的IP地址的結果相同。這就是inet_aton()更好的原因。)

9.13.0.4例子

struct sockaddr_in antelope;char *some_addr;inet_aton("10.0.0.1", &antelope.sin_addr); // store IP in antelopesome_addr = inet_ntoa(antelope.sin_addr); // return the IPprintf("%s\n", some_addr); // prints "10.0.0.1"// and this call is the same as the inet_aton() call, above:antelope.sin_addr.s_addr = inet_addr("10.0.0.1");

9.13.0.5另見

inet_ntop()`,`inet_pton``()`,`gethokbyname(),gethokbyaddr()

9.14inet_ntop()、inet_pton()

將IP地址轉換為人類可讀的形式并返回。

9.14.0.1簡介

#include <arpa/inet.h> const char *inet_ntop(int af, const void *src, char *dst, socklen_t size); int inet_pton(int af, const char *src, void *dst);

9.14.0.2描述

這些函數用于處理人類可讀的IP地址,并將其轉換為二進制表示,用于各種函數和系統調用。“n”代表“網絡”,“p”代表“呈現”。或者“文本呈現”。但是你可以把它想象成“可打印的”。“ntop”是“網絡到可打印的”。看到了嗎?

有時,在查看IP地址時,您不想查看一堆二進制數字。您希望它以可打印的形式顯示,如192.0.2.180或2001:db8:8714:3a90::12。在這種情況下,inet_ntop()適合您。

inet_ntop()接受af參數中的地址系列(AF_INET或AF_INET6)。src參數應該是指向結構in_addr或結構in6_addr的指針,其中包含您希望轉換為字符串的地址。最后,dst和size是指向目標字符串的指針以及該字符串的最大長度。

dst字符串的最大長度應該是多少?IPv4和IPv6地址的最大長度是多少?幸運的是,有幾個宏可以幫助你。最大長度是:INET_ADDRSTRLEN和INET6_ADDRSTRLEN。

其他時候,您可能有一個包含可讀形式的IP地址的字符串,并且您希望將其打包到結構sockaddr_in或結構sockaddr_in6中。在這種情況下,相反的funcioninet_pton()是您要尋找的。

inet_pton()在af參數中也接受一個地址系列(AF_INET或AF_INET6)。src參數是指向包含可打印形式的IP地址的字符串的指針。最后,dst參數指向結果應該存儲的地方,這可能是一個結構in_addr或結構in6_addr。

這些函數不做DNS查找-為此您需要getaddrinfo()。

9.14.0.3返回值

inet_ntop()在成功時返回dst參數,在失敗時返回NULL(并設置errno)。

inet_pton()在成功時返回1。如果有錯誤(errno被設置),它返回-1;如果輸入不是有效的IP地址,它返回0。

9.14.0.4例子

// IPv4 demo of inet_ntop() and inet_pton()struct sockaddr_in sa;char str[INET_ADDRSTRLEN];// store this IP address in sa:inet_pton(AF_INET, "192.0.2.33", &(sa.sin_addr));// now get it back and print itinet_ntop(AF_INET, &(sa.sin_addr), str, INET_ADDRSTRLEN);printf("%s\n", str); // prints "192.0.2.33"// IPv6 demo of inet_ntop() and inet_pton()// (basically the same except with a bunch of 6s thrown around)struct sockaddr_in6 sa;char str[INET6_ADDRSTRLEN];// store this IP address in sa:inet_pton(AF_INET6, "2001:db8:8714:3a90::12", &(sa.sin6_addr));// now get it back and print itinet_ntop(AF_INET6, &(sa.sin6_addr), str, INET6_ADDRSTRLEN);printf("%s\n", str); // prints "2001:db8:8714:3a90::12"// Helper function you can use://Convert a struct sockaddr address to a string, IPv4 and IPv6:char *get_ip_str(const struct sockaddr *sa, char *s, size_t maxlen){ switch(sa->sa_family) { case AF_INET: inet_ntop(AF_INET, &(((struct sockaddr_in *)sa)->sin_addr), s, maxlen); break; case AF_INET6: inet_ntop(AF_INET6, &(((struct sockaddr_in6 *)sa)->sin6_addr), s, maxlen); break; default: strncpy(s, "Unknown AF", maxlen); return NULL; } return s;}

9.14.0.5查看

#####################################################################################

9.15聽()

告訴套接字監聽傳入連接

9.15.0.1簡介

#include <sys/socket.h> int listen(int s, int backlog);

9.15.0.2描述

您可以使用套接字描述符(由套接字()系統調用生成)并告訴它偵聽傳入的連接。這就是服務器和客戶端的區別,伙計們。

積壓參數可能意味著不同的東西,這取決于你所在的系統,但大致上是指在內核開始拒絕新連接之前,你可以有多少個掛起的連接。所以當新連接進來時,你應該很快接受它們,這樣積壓就不會被填滿。試著把它設置為10左右,如果你的客戶端在重載下開始收到“連接拒絕”,把它設置得更高。

在調用listk()之前,服務器應該調用bind()將自己附加到一個特定的端口號。該端口號(在服務器的IP地址上)將是客戶端連接到的端口號。

9.15.0.3返回值

成功時返回零,錯誤時返回-1(errno將相應地設置)。

9.15.0.4例子

struct addrinfo hints, *res;int sockfd;// first, load up address structs with getaddrinfo():memset(&hints, 0, sizeof hints);hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whicheverhints.ai_socktype = SOCK_STREAM;hints.ai_flags = AI_PASSIVE; // fill in my IP for megetaddrinfo(NULL, "3490", &hints, &res);// make a socket:sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);// bind it to the port we passed in to getaddrinfo():bind(sockfd, res->ai_addr, res->ai_addrlen);listen(sockfd, 10); // set s up to be a server (listening) socket// then have an accept() loop down here somewhere

9.15.0.5另見

接受(),綁定(),套接字()

9.16 perror()

將錯誤打印為可讀字符串

9.16.0.1簡介

#include <stdio.h> #include <string.h> // for strerror() void perror(const char *s); char *strerror(int errnum);

9.16.0.2說明

由于許多函數在錯誤時返回-1,并將變量errno的值設置為某個數字,如果您可以輕松地以對您有意義的形式打印該值,那將是非常好的。

幸運的是,perror()做到了這一點。如果您希望在錯誤之前打印更多的描述,您可以將參數s指向它(或者您可以將s保留為NULL,并且不會打印任何其他內容)。

簡而言之,這個函數接受errno值,如ECONNRESET,并很好地打印它們,如“對等連接重置”

函數strirror()與perror()非常相似,只是它返回一個指向給定值的錯誤消息字符串的指針(通常會傳入變量errno)。

9.16.0.3返回值

Strerror()返回指向錯誤消息字符串的指針。

9.16.0.4實例

int s;s = socket(PF_INET, SOCK_STREAM, 0);if (s == -1) { // some error has occurred // prints "socket error: " + the error message: perror("socket error");}// similarly:if (listen(s, 10) == -1) { // this prints "an error: " + the error message from errno: printf("an error: %s\n", strerror(errno));}

9.16.0.5也看

伊爾諾

9.17投票()

同時測試多個套接字上的事件

9.17.0.1簡介

#include <sys/poll.h> int poll(struct pollfd *ufds, unsigned int nfds, int timeout);

9.17.0.2描述

這個函數與Select()非常相似,因為它們都監視事件的文件描述符集,例如傳入數據準備好recv()、套接字準備好發送()數據、帶外數據準備好recv()、錯誤等。

其基本思想是,在ufds中傳遞一個nfds結構的數組,以及一個以毫秒為單位的超時(每秒1000毫秒)。如果您想永遠等待,超時可以是負的。如果超時時沒有任何事件發生在任何套接字描述符上,將返回投票()。

每一個元素都代表一個套接字描述符,并包含以下字段: struct pollfd { int fd; // the socket descriptor short events; // bitmap of events we're interested in short revents; // when poll() returns, bitmap of events that occurred };在調用輪詢()之前,用套接字描述符加載fd(如果您將fd設置為負數,則忽略此結構圖,并將其Revents字段設置為零),然后通過按位ORing以下宏來構造事件字段:

MacroDescriptionPOLLINAlert me when data is ready to recv() on this socket.POLLOUTAlert me when I can send() data to this socket without blocking.POLLPRIAlert me when out-of-band data is ready to recv() on this socket.

一旦調用返回,Revents字段將被構造為上述字段的按位或,告訴您哪些描述符實際發生了該事件。此外,這些其他字段可能存在:

MacroDescriptionPOLLERRAn error has occurred on this socket.POLLHUPThe remote side of the connection hung up.POLLNVALSomething was wrong with the socket descriptor fd—maybe it’s uninitialized?

9.17.0.3返回值

返回ufds數組中發生事件的元素數;如果超時發生,這可以是零。在錯誤時也返回-1(errno將相應地設置)。

9.17.0.4例子

int s1, s2;int rv;char buf1[256], buf2[256];struct pollfd ufds[2];s1 = socket(PF_INET, SOCK_STREAM, 0);s2 = socket(PF_INET, SOCK_STREAM, 0);// pretend we've connected both to a server at this point//connect(s1, ...)...//connect(s2, ...)...// set up the array of file descriptors. in this example, we want to know when there's normal or out-of-band// data ready to be recv()'d...ufds[0].fd = s1;ufds[0].events = POLLIN | POLLPRI; // check for normal or out-of-bandufds[1].fd = s2;ufds[1].events = POLLIN; // check for just normal data// wait for events on the sockets, 3.5 second timeoutrv = poll(ufds, 2, 3500);if (rv == -1) { perror("poll"); // error occurred in poll()} else if (rv == 0) { printf("Timeout occurred! No data after 3.5 seconds.\n");} else { // check for events on s1: if (ufds[0].revents & POLLIN) { recv(s1, buf1, sizeof buf1, 0); // receive normal data } if (ufds[0].revents & POLLPRI) { recv(s1, buf1, sizeof buf1, MSG_OOB); // out-of-band data } // check for events on s2: if (ufds[1].revents & POLLIN) { recv(s1, buf2, sizeof buf2, 0); }}

9.17.0.5另見

選擇()

9.18 recv(), recvfrom()

在套接字上接收數據

9.18.0.1簡介

#include <sys/types.h> #include <sys/socket.h> ssize_t recv(int s, void *buf, size_t len, int flags); ssize_t recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen);

9.18.0.2說明

一旦建立并連接了套接字,就可以使用recv()(用于TCPSOCK_STREAM套接字)和recvfrom()(用于UDPSOCK_DGRAM套接字)從遠程端讀取傳入數據。

這兩個函數都使用套接字描述符s、緩沖區buf的指針、緩沖區len的大小(以字節為單位)以及一組控制函數工作方式的標志。

另外,recvfrom()需要一個struct solkaddr*,它將告訴您數據來自哪里,并將在fromlen中填入struct solkaddr的大小。(您還必須將fromlen初始化為from或structsokaddr的大小。)

那么,您可以將哪些奇妙的標志傳遞給這個函數呢?這里有一些,但是您應該檢查您的本地手冊頁面以獲得更多信息以及您的系統實際上支持什么。您可以按位或將這些放在一起,或者如果您希望它是常規的香草recv(),只需將標志設置為0。

MacroDescriptionMSG_OOBReceive Out of Band data. This is how to get data that has been sent to you with the MSG_OOB flag in send(). As the receiving side, you will have had signal SIGURG raised telling you there is urgent data. In your handler for that signal, you could call recv() with this MSG_OOB flag.MSG_PEEKIf you want to call recv() “just for pretend”, you can call it with this flag. This will tell you what’s waiting in the buffer for when you call recv() “for real” (i.e. without the MSG_PEEK flag. It’s like a sneak preview into the next recv() call.MSG_WAITALLTell recv() to not return until all the data you specified in the len parameter. It will ignore your wishes in extreme circumstances, however, like if a signal interrupts the call or if some error occurs or if the remote side closes the connection, etc. Don’t be mad with it.

當您調用recv()時,它會阻塞,直到有一些數據要讀取。如果您不想阻塞,請將套接字設置為非阻塞,或者在調用recv()或recvfrom()之前檢查是否有傳入數據。

9.18.0.3返回值

返回實際接收的字節數(可能小于len參數中請求的字節數),或-1(并相應地設置errno)。

如果遠程端關閉了連接,recv()將返回0。這是確定遠程端是否關閉連接的正常方法。正常是好的,叛逆!

9.18.0.4實例

// stream sockets and recv()struct addrinfo hints, *res;int sockfd;char buf[512];int byte_count;// get host info, make socket, and connect itmemset(&hints, 0, sizeof hints);hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whicheverhints.ai_socktype = SOCK_STREAM;getaddrinfo("www.example.com", "3490", &hints, &res);sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);connect(sockfd, res->ai_addr, res->ai_addrlen);// all right! now that we're connected, we can receive some data!byte_count = recv(sockfd, buf, sizeof buf, 0);printf("recv()'d %d bytes of data in buf\n", byte_count);// datagram sockets and recvfrom()struct addrinfo hints, *res;int sockfd;int byte_count;socklen_t fromlen;struct sockaddr_storage addr;char buf[512];char ipstr[INET6_ADDRSTRLEN];// get host info, make socket, bind it to port 4950memset(&hints, 0, sizeof hints);hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whicheverhints.ai_socktype = SOCK_DGRAM;hints.ai_flags = AI_PASSIVE;getaddrinfo(NULL, "4950", &hints, &res);sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);bind(sockfd, res->ai_addr, res->ai_addrlen);// no need to accept(), just recvfrom():fromlen = sizeof addr;byte_count = recvfrom(sockfd, buf, sizeof buf, 0, &addr, &fromlen);printf("recv()'d %d bytes of data in buf\n", byte_count);printf("from IP address %s\n", inet_ntop(addr.ss_family, addr.ss_family == AF_INET? ((struct sockadd_in *)&addr)->sin_addr: ((struct sockadd_in6 *)&addr)->sin6_addr, ipstr, sizeof ipstr);

9.18.0.5也看

發送``()``,發送(),``選擇()``,輪詢(),阻塞

9.19選擇()

檢查套接字描述符是否已準備好讀/寫

9.19.0.1簡介

#include <sys/select.h> int select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); FD_SET(int fd, fd_set *set); FD_CLR(int fd, fd_set *set); FD_ISSET(int fd, fd_set *set); FD_ZERO(fd_set *set);

9.19.0.2描述

Select()函數為您提供了一種同時檢查多個套接字的方法,看看它們是否有數據等待recv()d,或者您是否可以在不阻塞的情況下向它們發送()數據,或者是否發生了一些異常。

您可以使用上面的FD_SET()宏填充套接字描述符集。一旦您有了套接字,您可以將它作為以下參數之一傳遞給函數:如果您想知道套接字中的任何一個何時準備好recv()數據,請讀取;如果任何套接字準備好發送()數據,請寫入;如果您需要知道任何套接字何時發生異常(錯誤),請執行exceptfds。如果您對這些類型的事件不感興趣,這些參數中的任何一個或所有參數都可以為NULL。選擇()返回后,集合中的值將被更改,以顯示哪些可以讀取或寫入,哪些有異常。

第一個參數,n是最高編號的套接字描述符(它們只是int,記得嗎?)加1。

最后,最后是結構時間值,超時,這讓您可以告訴selc()檢查這些集合的時間。它將在超時后返回,或者當事件發生時返回,以先發生者為準。結構時間值有兩個字段:tv_sec是秒數,tv_usec加上微秒數(每秒1,000,000微秒)。

輔助宏執行以下操作:

MacroDescriptionFD_SET(int fd, fd_set *set);Add fd to the set.FD_CLR(int fd, fd_set *set);Remove fd from the set.FD_ISSET(int fd, fd_set *set);Return true if fd is in the set.FD_ZERO(fd_set *set);Clear all entries from the set.

Linux用戶請注意:Linux的Select()可以返回“準備好閱讀”,然后實際上沒有準備好閱讀,從而導致后續的read()調用被阻止。您可以通過在接收套接字上設置O_NONBLOCK標志來解決這個問題,這樣它就會出現EWOULDBLOCK錯誤,然后在出現錯誤時忽略這個錯誤。有關將套接字設置為非阻塞的更多信息,請參閱fcntl()參考頁面。

9.19.0.3返回值

成功時返回集合中描述符的數量,如果達到超時則返回0,如果出錯則返回-1(并相應地設置errno)。此外,還會修改集合以顯示哪些套接字已準備就緒。

9.19.0.4例子

int s1, s2, n;fd_set readfds;struct timeval tv;char buf1[256], buf2[256];// pretend we've connected both to a server at this point//s1 = socket(...);//s2 = socket(...);//connect(s1, ...)...//connect(s2, ...)...// clear the set ahead of timeFD_ZERO(&readfds);// add our descriptors to the setFD_SET(s1, &readfds);FD_SET(s2, &readfds);// since we got s2 second, it's the "greater", so we use that for// the n param in select()n = s2 + 1;// wait until either socket has data ready to be recv()d (timeout 10.5 secs)tv.tv_sec = 10;tv.tv_usec = 500000;rv = select(n, &readfds, NULL, NULL, &tv);if (rv == -1) { perror("select"); // error occurred in select()} else if (rv == 0) { printf("Timeout occurred! No data after 10.5 seconds.\n");} else { // one or both of the descriptors have data if (FD_ISSET(s1, &readfds)) { recv(s1, buf1, sizeof buf1, 0); } if (FD_ISSET(s2, &readfds)) { recv(s2, buf2, sizeof buf2, 0); }}

9.19.0.5查看

投票()

9.20 setsokopt(),getsokopt()

為套接字設置各種選項

9.20.0.1簡介

#include <sys/types.h>#include <sys/socket.h>int getsockopt(int s, int level, int optname, void *optval,socklen_t *optlen);int setsockopt(int s, int level, int optname, const void *optval,socklen_t optlen);

9.20.0.2描述

套接字是相當可配置的野獸。事實上,它們是如此可配置,我甚至不打算在這里涵蓋所有這些。不管怎樣,它可能依賴于系統。但是我將談談基礎知識。

顯然,這些函數獲取并設置套接字上的某些選項。在Linux框中,所有套接字信息都在第7節的套接字手冊頁面中。(鍵入“man 7套接字”以獲取所有這些好東西。)

至于參數,s是您正在談論的套接字,級別應該設置為SOL_SOCKET。然后您將optname設置為您感興趣的名稱。同樣,請參閱您的手冊頁面了解所有選項,但以下是一些最有趣的選項:

optnameDescriptionSO_BINDTODEVICEBind this socket to a symbolic device name like eth0 instead of using bind() to bind it to an IP address. Type the command ifconfig under Unix to see the device names.SO_REUSEADDRAllows other sockets to bind() to this port, unless there is an active listening socket bound to the port already. This enables you to get around those “Address already in use” error messages when you try to restart your server after a crash.SOCK_DGRAMAllows UDP datagram (SOCK_DGRAM) sockets to send and receive packets sent to and from the broadcast address. Does nothing—NOTHING!!—to TCP stream sockets! Hahaha!

至于參數optval,它通常是指向一個int的指針,指示所討論的值。對于布爾值,零是假的,非零是真的。這是絕對的事實,除非在你的系統上有所不同。如果沒有要傳遞的參數,optval可以是NULL。

最后一個參數optlen應該設置為optval的長度,可能是sizeofint),但是根據選項的不同而變化。請注意,在get門選擇()的情況下,這是一個指向socklen_t的指針,它指定了將存儲在optval中的最大大小對象(以防止緩沖區溢出)。get門選擇()將修改optlen的值以反映實際設置的字節數。

警告:在某些系統(特別是Sun和Windows)上,選項可以是char而不是int,并且被設置為,例如,字符值為'1'而不是int值為1。同樣,請使用“man setsokpt”和“man 7套接字”查看您自己的手冊頁面以獲取更多信息!

9.20.0.3返回值

成功時返回零,錯誤時返回-1(errno將相應地設置)。

9.20.0.4例子

int optval; int optlen; char *optval2;// set SO_REUSEADDR on a socket to true (1): optval = 1; setsockopt(s1, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof optval);// bind a socket to a device name (might not work on all systems): optval2 = "eth1"; // 4 bytes long, so 4, below: setsockopt(s2, SOL_SOCKET, SO_BINDTODEVICE, optval2, 4);// see if the SO_BROADCAST flag is set: getsockopt(s3, SOL_SOCKET, SO_BROADCAST, &optval, &optlen); if (optval != 0) {print("SO_BROADCAST enabled on s3!\n"); }

9.20.0.5另見

FCNTL()

9.21發送(),發送()

通過套接字發送數據

9.21.0.1簡介

#include <sys/types.h> #include <sys/socket.h> ssize_t send(int s, const void *buf, size_t len, int flags); ssize_t sendto(int s, const void *buf, size_t len, int flags, const struct sockaddr *to, socklen_t tolen);

9.21.0.2說明

這些函數將數據發送到套接字。一般來說,sen()用于TCPSOCK_STREAM連接的套接字,sendto()用于UDPSOCK_DGRAM未連接的數據報套接字。對于未連接的套接字,每次發送數據包時都必須指定數據包的目的地,這就是為什么sendto()的最后一個參數定義數據包的去向。

對于mail()和sendto(),參數s是套接字,buf是要發送數據的指針,len是要發送的字節數,標志允許您指定有關數據如何發送的更多信息。如果您希望它是“正常”數據,請將標志設置為零。以下是一些常用的標志,但請查看您本地的“發送()手冊”頁面了解更多詳細信息:

MacroDescriptionMSG_OOBSend as “out of band” data. TCP supports this, and it’s a way to tell the receiving system that this data has a higher priority than the normal data. The receiver will receive the signal SIGURG and it can then receive this data without first receiving all the rest of the normal data in the queue.MSG_DONTROUTEDon’t send this data over a router, just keep it local.MSG_DONTWAITIf send() would block because outbound traffic is clogged, have it return EAGAIN. This is like a “enable non-blocking just for this send.” See the section on blocking for more details.MSG_NOSIGNALIf you send() to a remote host which is no longer recv()ing, you’ll typically get the signal SIGPIPE. Adding this flag prevents that signal from being raised.

9.21.0.3返回值

返回實際發送的字節數,或錯誤時的-1(errno將相應設置)。請注意,實際發送的字節數可能小于您要求它發送的字節數!有關幫助函數的解決方法,請參閱處理部分發送()的部分。

此外,如果任何一方都關閉了套接字,調用發送()的進程將獲得信號SIGPIPE。(除非用MSG_NOSIGNAL標志調用了發送()。)

9.21.0.4實例

int spatula_count = 3490; char *secret_message = "The Cheese is in The Toaster";int stream_socket, dgram_socket; struct sockaddr_in dest; int temp;// first with TCP stream sockets:// assume sockets are made and connected //stream_socket = socket(... //connect(stream_socket, ...// convert to network byte order temp = htonl(spatula_count); // send data normally: send(stream_socket, &temp, sizeof temp, 0);// send secret message out of band: send(stream_socket, secret_message, strlen(secret_message)+1, MSG_OOB);// now with UDP datagram sockets: //getaddrinfo(... //dest = ... // assume "dest" holds the address of the destination //dgram_socket = socket(...// send secret message normally: sendto(dgram_socket, secret_message, strlen(secret_message)+1, 0, (struct sockaddr*)&dest, sizeof dest);

9.21.0.5也看

Recv(), recvfrom()

9.22關機()

停止在套接字上的進一步發送和接收

9.22.0.1簡介

#include <sys/socket.h>int shutdown(int s, int how);

9.22.0.2描述

就是這樣!我受夠了!這個套接字上不允許再發送()了,但是我仍然想在上面接收()數據!反之亦然!我該怎么做呢?

當您關閉()一個套接字描述符時,它關閉了用于讀寫的套接字的兩邊,并釋放了套接字描述符,如果您只是想關閉一邊或另一邊,您可以使用這個關閉()調用。

至于參數,s顯然是您要執行此操作的套接字,可以使用how參數指定該操作。如何SHUT_RD以防止進一步recv()s,SHUT_WR禁止進一步發送()s,或者SHUT_RDWR兩者兼而有之。

請注意,Shutdown()不會釋放套接字描述符,因此即使套接字已經完全關閉,您最終仍必須關閉()套接字。

這是一個很少使用的系統調用。

9.22.0.3返回值

成功時返回零,錯誤時返回-1(errno將相應地設置)。

9.22.0.4例子

int s = socket(PF_INET, SOCK_STREAM, 0);// ...do some send()s and stuff in here...// and now that we're done, don't allow any more sends()s: shutdown(s, SHUT_WR);

9.22.0.5另見

關閉()

9.23套接字()

分配套接字描述符

9.23.0.1簡介

#include <sys/types.h>#include <sys/socket.h>int socket(int domain, int type, int protocol);

9.23.0.2說明

返回一個新的套接字描述符,您可以用它來做一些特殊的事情。這通常是編寫套接字程序的龐大過程中的第一次調用,您可以使用這個結果進行后續調用,以監聽()、綁定()、接受()或各種其他函數。

在通常的使用中,您可以通過調用getaddrinfo()來獲得這些參數的值,如下面的示例所示。但是如果您真的想的話,您可以手工填寫它們。

MacroDescriptiondomaindomain describes what kind of socket you’re interested in. This can, believe me, be a wide variety of things, but since this is a socket guide, it’s going to be PF_INET for IPv4, and PF_INET6 for IPv6.typeAlso, the type parameter can be a number of things, but you’ll probably be setting it to either SOCK_STREAM for reliable TCP sockets (send(), recv()) or SOCK_DGRAM for unreliable fast UDP sockets (sendto(), recvfrom()). (Another interesting socket type is SOCK_RAW which can be used to construct packets by hand. It’s pretty cool.)protocolFinally, the protocol parameter tells which protocol to use with a certain socket type. Like I’ve already said, for instance, SOCK_STREAM uses TCP. Fortunately for you, when using SOCK_STREAM or SOCK_DGRAM, you can just set the protocol to 0, and it’ll use the proper protocol automatically. Otherwise, you can use getprotobyname() to look up the proper protocol number.

9.23.0.3返回值

將在后續調用中使用的新套接字描述符,或-1 on false(并且errno將相應地設置)。

9.23.0.4實例

struct addrinfo hints, *res; int sockfd;// first, load up address structs with getaddrinfo():memset(&hints, 0, sizeof hints); hints.ai_family = AF_UNSPEC; // AF_INET, AF_INET6, or AF_UNSPEC hints.ai_socktype = SOCK_STREAM; // SOCK_STREAM or SOCK_DGRAMgetaddrinfo("www.example.com", "3490", &hints, &res);// make a socket using the information gleaned from getaddrinfo(): sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);

9.23.0.5也看

接受``()``,``綁定()``,getaddrinfo(),``聽(``)

9.24結構sokaddr和朋友

處理互聯網地址的結構

9.24.0.1簡介

#include <netinet/in.h>// All pointers to socket address structures are often cast to pointers// to this type before use in various functions and system calls:struct sockaddr {unsigned short sa_family; // address family, AF_xxxchar sa_data[14]; // 14 bytes of protocol address};// IPv4 AF_INET sockets:struct sockaddr_in {short sin_family; // e.g. AF_INET, AF_INET6unsigned short sin_port; // e.g. htons(3490)struct in_addr sin_addr; // see struct in_addr, belowchar sin_zero[8]; // zero this if you want to};struct in_addr {unsigned long s_addr; // load with inet_pton()};// IPv6 AF_INET6 sockets:struct sockaddr_in6 {u_int16_t sin6_family; // address family, AF_INET6u_int16_t sin6_port; // port number, Network Byte Orderu_int32_t sin6_flowinfo; // IPv6 flow informationstruct in6_addr sin6_addr; // IPv6 addressu_int32_t sin6_scope_id; // Scope ID};struct in6_addr {unsigned char s6_addr[16]; // load with inet_pton()};// General socket address holding structure, big enough to hold either// struct sockaddr_in or struct sockaddr_in6 data:struct sockaddr_storage {sa_family_t ss_family; // address family// all this is padding, implementation specific, ignore it:char __ss_pad1[_SS_PAD1SIZE];int64_t __ss_align;char __ss_pad2[_SS_PAD2SIZE];};

9.24.0.2描述

這些是所有處理互聯網地址的系統和函數的基本結構。通常您會使用getaddrinfo()來填寫這些結構,然后在必要時閱讀它們。

在內存中,結構體sockaddr_in和結構體sockaddr_in6與結構體sokaddr共享相同的開始結構,您可以自由地將一種類型的指針投擲到另一種類型,而不會受到任何傷害,除了可能的宇宙末日。

在宇宙末日的事情上開玩笑…如果宇宙真的在你向一個結構sockaddr_in*投下一個結構時結束了,我向你保證這純粹是巧合,你甚至不應該擔心。

因此,記住這一點,請記住,每當一個函數說它需要一個結構sokaddr*時,您可以輕松安全地將您的結構sockaddr_in*、結構sockaddr_in6*或結構sockadd_storage*轉換為該類型。

結構sockaddr_in是用于IPv4地址(例如192.0.2.10)的結構。它持有地址系列(AF_INET)、sin_port端口和sin_addrIPv4地址。

結構體sockaddr_in中還有一個sin_zero字段,有些人聲稱必須將其設置為零。其他人對此一無所知(Linux文檔甚至根本沒有提到它),并且將其設置為零似乎實際上沒有必要。所以,如果你喜歡,使用memset()將其設置為零。

現在,這個結構in_addr在不同的系統上是一個奇怪的野獸。有時它是一個包含各種#定義和其他廢話的瘋狂聯盟。但是你應該做的是只在這個結構中使用s_addr字段,因為許多系統只實現那個。

結構sockadd_in6和結構in6_addr非常相似,只是它們用于IPv6。

結構sockaddr_storage是一個結構,當您試圖編寫與IP版本無關的代碼,并且您不知道新地址是IPv4還是IPv6時,您可以通過該結構接受()或recvfrom()。結構sockaddr_storage結構足夠大,可以容納這兩種類型,不像最初的小結構sokaddr。

9.24.0.3實例

// IPv4:struct sockaddr_in ip4addr; int s;ip4addr.sin_family = AF_INET; ip4addr.sin_port = htons(3490); inet_pton(AF_INET, "10.0.0.1", &ip4addr.sin_addr);s = socket(PF_INET, SOCK_STREAM, 0); bind(s, (struct sockaddr*)&ip4addr, sizeof ip4addr); // IPv6:struct sockaddr_in6 ip6addr; int s;ip6addr.sin6_family = AF_INET6; ip6addr.sin6_port = htons(4950); inet_pton(AF_INET6, "2001:db8:8714:3a90::12", &ip6addr.sin6_addr);s = socket(PF_INET6, SOCK_STREAM, 0); bind(s, (struct sockaddr*)&ip6addr, sizeof ip6addr);

9.24.0.4也看

接受(),綁定(),連接(),inet_aton()``,inet_ntoa()

10更多參考資料

你已經走了這么遠,現在你尖叫著要更多!你還能去哪里了解更多這些東西?

10.1書籍

對于真正的老式紙質書,試試以下幾本好書。這些書會重定向到受歡迎書商的會員鏈接,給我豐厚的回扣。如果你只是覺得慷慨,你可以向beej@beej.us捐款。:-)

Unix網絡編程,W. Richard Stevens的第1-2卷。Addison-Wesley專業和PrenticeHall出版。1-2: 978-013141155549, 978-013081081650****卷的ISBN。

**與TCP/IP聯網,**Douglas E. Comer第一卷,Pearson出版社,ISBN978-013608530051。

TCP/IP插圖,第1-3卷,W. Richard Stevens和Gary R. Wright著。Addison Wesley出版。第1、2和3卷的ISBN(和一套3卷的ISBN):978-020163346752, 978-020163354253, 978-020163495254, (978-020177631755)。

Craig Hunt的TCP/IP網絡管理。O’Reilly&Associates,Inc.出版。ISBN978-059600297856。

UNIX環境中的高級編程,W. Richard Stevens著,Addison Wesley出版社,ISBN978-032163773457。

10.2網站參考

在網絡上:

BSD套接字:一個快速和骯臟的****Primer58(Unix系統編程信息,太!)

Unix套接字常見問題59

TCP/IP****常見問題

Winsock常見問題61

以下是一些相關的維基百科頁面:

伯克利****Sockets62

網絡之間互連的協議****(IP)63

傳輸控制協議****(TCP)64

用戶數據報協議****(UDP)65

客戶端服務器

序列化67(**包裝**和拆包數據)

10.3 RFC

RFCs68——真正的污垢!這些是描述分配號碼、編程API和互聯網上使用的協議的文檔。我在這里提供了其中一些的鏈接,供你享受,所以拿一桶爆米花,戴上你的思考帽:

RFC**** 169——第一個RFC;這讓你了解了“互聯網”剛剛誕生時的樣子,并深入了解了它是如何從頭開始設計的。(顯然,這個RFC已經完全過時了!)

RFC**** 76870-用戶數據報協議(UDP)

RFC**** 79171-網絡之間互連的協議(IP)

RFC**** 79372-傳輸控制協議(TCP)

RFC**** 85473-Telnet協議

RFC**** 95974-文件傳輸協議(FTP)

RFC**** 135075-瑣碎的文件傳輸協議(TFTP)

RFC**** 145976-互聯網中繼聊天協議(IRC)

RFC**** 191877-專用互聯網的地址分配

RFC**** 213178-動態主機配置協議(DHCP)

RFC**** 261679-超文本傳輸協議(HTTP)

RFC**** 282180-簡單郵件傳輸協議(SMTP)

RFC**** 333081-特殊用途IPv4地址

RFC**** 349382-IPv6的基本套接字接口擴展

RFC**** 354283-用于IPv6的高級套接字應用程序接口(API)

RFC**** 384984-為文檔保留的IPv6地址前綴

RFC**** 392085-可擴展消息和存在協議(XMPP)

RFC**** 397786-網絡新聞傳輸協議(NNTP)

唯一的本地IPv6單播地址

RFC**** 450688-外部數據表示標準(XDR)

IETF有一個很好的在線搜索和瀏覽RFCs89的工具。

  • https://www.linux.com/?
  • https://bsd.org/?
  • https://cygwin.com/?
  • https://docs.microsoft.com/en-us/windows/wsl/about??
  • https://tangentsoft.net/wskfaq/?
  • http://www.catb.org/~esr/faqs/smart-questions.html?
  • https://beej.us/guide/bgnet/examples/telnot.c??
  • https://tools.ietf.org/html/rfc854?
  • https://tools.ietf.org/html/rfc793?
  • https://tools.ietf.org/html/rfc791?
  • https://tools.ietf.org/html/rfc768 ?
  • https://tools.ietf.org/html/rfc791 ?
  • https://en.wikipedia.org/wiki/Vint_Cerf?
  • https://en.wikipedia.org/wiki/ELIZA ?
  • https://www.iana.org/assignments/port-numbers ?
  • https://en.wikipedia.org/wiki/Doom_(1993_video_game)?
  • https://en.wikipedia.org/wiki/Wilford_Brimley?
  • https://tools.ietf.org/html/rfc1918 ?
  • https://tools.ietf.org/html/rfc4193 ?
  • https://www.iana.org/assignments/port-numbers ?
  • https://beej.us/guide/bgnet/examples/showip.c ?
  • https://tools.ietf.org/html/rfc1413 ?
  • https://beej.us/guide/bgnet/examples/server.c ?
  • https://beej. us/guide/bgnet/examples/client. c?
  • https://beej.us/guide/bgnet/examples/listener.c?
  • https://beej.us/guide/bgnet/examples/talker.c?
  • https://libevent.org/?
  • https://beej.us/guide/bgnet/examples/poll.c?
  • https://beej.us/guide/bgnet/examples/pollserver.c?
  • https://libevent.org/?
  • https://beej.us/guide/bgnet/examples/select.c?
  • https://beej.us/guide/bgnet/examples/selectserver.c??
  • https://en.wikipedia.org/wiki/Internet_Relay_Chat?
  • https://beej.us/guide/bgnet/examples/pack.c??
  • https://en.wikipedia.org/wiki/IEEE_754?
  • https://beej.us/guide/bgnet/examples/ieee754.c ?
  • https://beej.us/guide/url/tpop ?
  • https://github.com/protobuf-c/protobuf-c ?
  • https://beej.us/guide/bgnet/examples/pack2.c ?
  • https://beej.us/guide/bgnet/examples/pack2.c ?!}
  • https://tools.ietf.org/html/rfc4506 ?
  • https://beej.us/guide/bgnet/examples/broadcaster.c ?
  • http://www.unpbook.com/src.html ?
  • http://www.unpbook.com/src.html ?!}
  • https://www.openssl.org/ ?
  • https://stack over flow. com/question/21323023/?
  • https://www. iana. org/assignments/port-numbers?!}
  • https://www. iana. org/assignments/port-numbers?
  • https://beej.us/guide/url/unixnet1?
  • https://beej.us/guide/url/unixnet2?
  • https://beej.us/guide/url/intertcp1?
  • https://beej.us/guide/url/tcpi1??
  • https://beej.us/guide/url/tcpi2?
  • https://beej.us/guide/url/tcpi3?
  • https://beej.us/guide/url/tcpi123?
  • https://beej.us/guide/url/tcpna??
  • https://beej.us/guide/url/advunix??
  • https://cis.temple.edu/~giorgio/old/cis307s96/readings/docs/sockets.html?
  • https://developerweb.net/?f=70 ?
  • http://www.faqs.org/faqs/internet/tcp-ip/tcp-ip-faq/part1/ ?!}
  • https://tangentsoft.net/wskfaq/ ?
  • https://en.wikipedia.org/wiki/Berkeley_sockets?
  • https://en.wikipedia.org/wiki/Internet_Protocol?
  • https://en.wikipedia.org/wiki/Transmission_Control_Protocol?
  • https://en.wikipedia.org/wiki/User_Datagram_Protocol的?
  • https://en.wikipedia.org/wiki/Client-server ?
  • https://en.wikipedia.org/wiki/Serialization ?
  • https://www.rfc-editor.org/ ?
  • https://tools.ietf.org/html/rfc1 ?
  • https://tools.ietf.org/html/rfc768 ?
  • https://tools.ietf.org/html/rfc791 ?
  • https://tools.ietf.org/html/rfc793 ?
  • https://tools.ietf.org/html/rfc854?
  • https://tools.ietf.org/html/rfc959?
  • https://tools.ietf.org/html/rfc1350?
  • https://tools.ietf.org/html/rfc1459??
  • https://tools.ietf.org/html/rfc1918?
  • https://tools.ietf.org/html/rfc2131?
  • https://tools.ietf.org/html/rfc2616?
  • https://tools.ietf.org/html/rfc2821??
  • https://tools.ietf.org/html/rfc3330?
  • https://tools.ietf.org/html/rfc3493?
  • https://tools.ietf.org/html/rfc3542 ?
  • https://tools.ietf.org/html/rfc3849 ?!}
  • https://tools.ietf.org/html/rfc3920 ?
  • https://tools.ietf.org/html/rfc3977 ?
  • https://tools.ietf.org/html/rfc4193 ?
  • https://tools.ietf.org/html/rfc4506 ?
  • https://tools.ietf.org/rfc/ [?](
  • 總結

    以上是生活随笔為你收集整理的Beej网络编程指南《三》的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    精品在线视频播放 | 久久黄色成人 | 免费看在线看www777 | 久久9精品 | 国内揄拍国内精品 | 中文资源在线播放 | 久久爱导航 | 欧美日韩视频在线一区 | 免费看黄色毛片 | 国产亚洲亚洲 | 国产精品嫩草55av | 久草在线最新视频 | 91爱爱免费观看 | 国产黄色精品在线 | 天天操天天操天天操天天操天天操 | 97超级碰碰碰视频在线观看 | 中文字幕区 | 日本精品久久久一区二区三区 | 欧美性春潮 | 精品高清美女精品国产区 | 欧美一区,二区 | 中文字幕九九 | 毛片精品免费在线观看 | 狠狠色狠狠色综合系列 | 久久99久久久久久 | 蜜桃av观看 | 免费精品 | 狠狠色丁香婷婷综合视频 | 精品久久一二三区 | 偷拍福利视频一区二区三区 | 狠狠色香婷婷久久亚洲精品 | 国产精品一区二区在线免费观看 | 国产视频一二区 | 久久国产精品久久精品国产演员表 | 国产伦精品一区二区三区… | 色a网| 91麻豆精品国产午夜天堂 | 四虎在线免费观看视频 | 九九久 | 97人人模人人爽人人喊中文字 | 97色se | 国产高清网站 | 欧美日韩久久 | 五月婷在线视频 | 欧美性生爱 | 色婷婷国产在线 | 久久久久久久久久久久久国产精品 | www色,com| 日韩精品资源 | 在线国产日韩 | 91精品国产综合久久久久久久 | av福利在线看 | 又湿又紧又大又爽a视频国产 | 手机av资源| 中文字幕亚洲综合久久五月天色无吗'' | 久草精品视频在线观看 | 日韩精品一区二区三区丰满 | 国产一区免费视频 | 狠狠狠色丁香婷婷综合激情 | 成人一区二区三区在线 | 中文字幕综合在线 | 人人爱夜夜操 | www.日日日.com | 久草免费在线视频 | 免费在线激情电影 | 色精品视频 | 亚洲免费精品一区二区 | 精品国产一区二区三区在线观看 | 国产一线二线三线性视频 | 国产一区视频免费在线观看 | 精品国产一区二区三区在线观看 | 亚洲精品视频在 | av在线免费网站 | 在线天堂日本 | 成人av在线直播 | 婷婷丁香花五月天 | 在线观看亚洲国产 | 日韩高清在线一区二区三区 | 亚洲视频综合在线 | 久久免费公开视频 | 五月天久久久久 | 日韩精品专区在线影院重磅 | 在线免费观看羞羞视频 | 久久久五月婷婷 | 国产成人综合图片 | 午夜私人影院久久久久 | 久久9视频 | 欧美亚洲国产日韩 | 在线电影 一区 | 婷婷丁香五 | 999久久久久久久久久久 | 午夜少妇 | 欧美精品久 | av看片网址 | 天天躁日日 | 99c视频高清免费观看 | 日韩色视频在线观看 | 成人9ⅰ免费影视网站 | 18做爰免费视频网站 | 24小时日本在线www免费的 | 深爱五月激情网 | 久草免费在线观看 | 亚洲精品在线电影 | 久久爱影视i | 免费在线观看成年人视频 | 国产婷婷色 | 男女啪啪免费网站 | 国产午夜精品福利视频 | 国产亚州精品视频 | 丝袜精品视频 | 热re99久久精品国产99热 | 国产精品区一区 | 久久99精品国产麻豆婷婷 | 在线观看激情av | 免费黄色小网站 | 午夜精品一区二区国产 | 西西大胆啪啪 | 一区二区三区韩国免费中文网站 | 日韩亚洲国产精品 | 亚洲免费在线 | 国内精品久久天天躁人人爽 | adc在线观看| 午夜视频在线网站 | 九色在线 | av网址最新| 久久视频在线免费观看 | 欧美一区二区伦理片 | 99精品视频播放 | 国产精品久久久久久久久久久免费看 | 亚洲永久av | 91精品国产福利 | 日韩二区三区在线观看 | 免费影视大全推荐 | av电影免费观看 | 91激情视频在线 | 久精品视频免费观看2 | 97超碰国产精品 | 国产精品伦一区二区三区视频 | 日韩大片在线免费观看 | ww亚洲ww亚在线观看 | 久久免费精品视频 | 欧美做受高潮 | 九九久久久久久久久激情 | 欧美日韩国产免费视频 | 国产一级视频 | 久久人人看 | 久草视频在线新免费 | 成人av久久 | 黄色在线视频网址 | 久久9999久久免费精品国产 | 人人澡人人爽欧一区 | 精品久久福利 | 久久精品中文字幕一区二区三区 | av在线一| 麻豆国产精品一区二区三区 | 公与妇乱理三级xxx 在线观看视频在线观看 | 成片视频在线观看 | 天天操天天干天天玩 | 在线播放av网址 | 九九久久精品 | 久久久久久久久久久久久久电影 | 国产在线a免费观看 | 亚洲视频在线免费看 | 97国产精品亚洲精品 | av三级在线免费观看 | 在线激情网 | 五月开心综合 | 国产精品久久麻豆 | 久久不卡日韩美女 | 国产精在线 | 欧美a级免费视频 | 激情五月婷婷综合 | 亚洲综合色av| 黄色成年片 | 日韩三级视频 | 久久国产精品一二三区 | 最近中文字幕国语免费高清6 | 欧美日韩一级在线 | 五月婷婷丁香色 | 高清在线观看av | 久久不射电影院 | 亚洲一区二区精品视频 | 久久久久久久久久久黄色 | 亚洲精品美女在线观看 | 亚洲天天在线日亚洲洲精 | 精品国产aⅴ麻豆 | 最近日本字幕mv免费观看在线 | 国产精品无av码在线观看 | 日韩资源在线观看 | 99精品视频在线免费观看 | 免费看三级网站 | 成年人国产精品 | 99久久久久久久 | 久久久久久久久久久网 | 国产韩国日本高清视频 | 国产一区在线视频播放 | 激情欧美一区二区三区免费看 | 久久99精品久久久久久久久久久久 | 日韩av一区二区在线播放 | 韩日在线一区 | 久久精品美女 | 欧美另类交人妖 | 97在线视频免费 | 精品日韩在线一区 | 免费av电影网站 | 免费看十八岁美女 | 国产一区免费视频 | 在线国产视频 | 欧美性色综合 | 日日操狠狠干 | 808电影| 免费在线黄色av | 月下香电影 | 亚洲最新av在线 | 91大片网站 | 久视频在线播放 | 色爱成人网 | 伊人永久在线 | 亚洲国产日本 | 国产理论片在线观看 | 国产精品久久久一区二区三区网站 | 黄色毛片一级片 | 91麻豆产精品久久久久久 | 日本中文乱码卡一卡二新区 | 美女网站在线看 | 国产精品毛片一区二区三区 | 五月天婷婷丁香花 | 国内精品久久久久久中文字幕 | 欧美精品在线观看一区 | 91超国产 | 成人a v视频 | 精品亚洲一区二区三区 | 久久久久久精 | 在线免费视频一区 | 中文字幕av在线免费 | 国产一线二线三线性视频 | av电影中文字幕在线观看 | 天堂视频中文在线 | 亚洲精品国产电影 | 日韩久久精品一区二区 | 一区二区三区在线电影 | 91精品视频在线观看免费 | 91av在线免费看 | 久久视精品 | 亚洲精品一区二区18漫画 | 成人在线观看网址 | 黄色亚洲| 四虎在线免费视频 | 亚洲国产欧美在线看片xxoo | 国产精品久久久久高潮 | 最新高清无码专区 | 欧美性爽爽 | 成年人网站免费在线观看 | 激情综合一区 | 天天综合色网 | 婷婷五月情| 久久精品老司机 | 色中色亚洲 | 日韩黄色在线电影 | 日本黄色大片免费 | 精品一区二区电影 | 亚洲视频每日更新 | 中文字幕在线看 | 一区二区三区四区五区在线 | 国产黄色片在线免费观看 | 欧美乱淫视频 | 久久精品一区二区三区中文字幕 | 日韩免费在线观看视频 | 亚洲成人黄 | 国产xxxx做受性欧美88 | 婷婷狠狠操 | 五月天久久精品 | 久草视频免费观 | 在线观看香蕉视频 | 欧美a级免费视频 | 亚洲综合少妇 | 网站免费黄色 | 日韩免费一区二区在线观看 | 欧美一二三专区 | 午夜视频在线观看一区二区三区 | 久久午夜网 | 国产精品12345 | 久久精品视频在线看 | 在线播放av网址 | 亚洲激情 欧美激情 | 992tv在线观看 | 人人爽人人爽人人片av | 久久中文欧美 | 亚洲第一色 | 成人黄色短片 | 国产精品免费在线观看视频 | 久久在线播放 | 国产中文字幕视频在线观看 | 久久久国产精品一区二区三区 | 午夜三级在线 | 久久久久久免费网 | 在线超碰av | 国产成人专区 | 九九免费精品视频 | 久久国产美女视频 | 日本精品视频免费 | www.香蕉| 婷婷色狠狠 | 亚洲1区在线 | 激情欧美日韩一区二区 | 亚洲精品中文字幕在线 | 国内精品久久久久影院一蜜桃 | 五月婷婷久草 | 韩国在线一区二区 | 久青草影院 | 很黄很黄的网站免费的 | 亚洲综合成人在线 | 在线观看免费版高清版 | 亚洲精品国产精品乱码不99热 | 91探花视频 | 亚洲永久精品一区 | 在线天堂中文在线资源网 | 精品欧美乱码久久久久久 | 日本精品在线看 | 欧美疯狂性受xxxxx另类 | 国产91aaa | 欧美日韩高清免费 | 久久少妇免费视频 | 人人澡人人干 | 成人av久久 | 亚洲国产资源 | 国产高清专区 | 最新中文字幕在线观看视频 | 五月婷婷激情 | 国产亚洲免费的视频看 | 国产亚洲欧洲 | 国产在线精品二区 | 国产日韩视频在线观看 | 亚洲激情在线观看 | 久久综合五月 | 国内精自线一二区永久 | 亚洲国产午夜 | 超碰在线观看99 | 九九九视频在线 | 欧美日产一区 | 天天操天天干天天综合网 | 国产精品久久久久9999 | 91丨九色丨蝌蚪丨对白 | 国产精品wwwwww| 97超碰国产在线 | 超碰99人人 | 国产精品免费视频网站 | 欧美激情片在线观看 | 婷婷综合电影 | 国产啊v在线观看 | 亚洲免费婷婷 | 国产精品国产亚洲精品看不卡 | 青青看片| 成年人网站免费在线观看 | 99热九九这里只有精品10 | 丁香在线视频 | 久久成人国产精品一区二区 | 黄污网站在线观看 | 日本中文字幕一二区观 | 久久蜜桃av| 五月开心激情 | 欧美一区二区三区免费观看 | 中文字幕在线观看免费观看 | 国产精品久久婷婷六月丁香 | 久久久久久久久久毛片 | 久操视频在线观看 | 99国产视频 | 久99视频 | av中文字幕第一页 | 最新av在线网址 | 日韩性色 | 中文字幕亚洲字幕 | 日韩三级视频 | 亚洲欧美国产精品久久久久 | 亚洲永久精品在线观看 | 中文字幕资源站 | 18国产精品白浆在线观看免费 | 日韩欧美精品在线 | 亚洲欧洲精品久久 | 国产激情小视频在线观看 | 一本大道久久精品懂色aⅴ 五月婷社区 | 伊人中文字幕在线 | 三级视频日韩 | 日日天天 | 国产精品无av码在线观看 | 国产一级二级在线播放 | 婷婷国产在线 | 精品你懂的 | 精品一二| 国产麻豆精品传媒av国产下载 | 一级片免费观看视频 | 免费在线一区二区 | 在线免费观看黄色小说 | 亚洲伊人成综合网 | 久久成电影 | 久久久 激情 | 欧美国产日韩一区 | 国产精品一区二区 91 | 亚洲免费视频观看 | 亚洲黄色在线 | 在线v片免费观看视频 | 中文字幕国产一区 | 在线观看久草 | 视频一区在线播放 | 全久久久久久久久久久电影 | 麻豆视频在线观看免费 | av在线播放观看 | 最新婷婷色 | 日韩免费福利 | 人人爽人人香蕉 | 99久久夜色精品国产亚洲96 | 日韩电影在线观看一区 | 日本bbbb摸bbbb| 欧美激情精品久久久久 | 亚洲国产成人高清精品 | 午夜美女av| a视频免费看 | 国产一级黄色片免费看 | 国产精品入口66mio女同 | 免费看国产视频 | 免费久久99精品国产 | 深爱激情亚洲 | 久久精品男人的天堂 | 最近久乱中文字幕 | 国产中的精品av小宝探花 | 中文字幕在线免费 | 在线电影中文字幕 | 久久尤物电影视频在线观看 | 久草在线最新视频 | 亚洲午夜久久久久久久久电影网 | 黄色亚洲免费 | 亚洲午夜精品久久久久久久久久久久 | 91中文字幕在线视频 | 国产激情久久久 | 亚一亚二国产专区 | 91亚洲精品久久久蜜桃网站 | 久久久久欠精品国产毛片国产毛生 | 色中色资源站 | 欧美在线a视频 | av三级在线免费观看 | 天天操天天操一操 | 狠狠gao | 中文字幕第一页av | 久久免费成人网 | 天天曰 | 色综合久久五月 | 成片视频在线观看 | 中文字幕中文字幕在线一区 | 五月婷婷在线视频观看 | 国产精品美女网站 | 在线观看成人福利 | 亚洲免费国产 | 九九视频网 | 99亚洲精品 | 免费高清在线视频一区· | 色夜影院| 激情欧美在线观看 | 久久精品免视看 | 日本mv大片欧洲mv大片 | 免费在线观看一区二区三区 | 欧美性色黄 | 亚洲欧美日韩精品久久奇米一区 | 精品一区欧美 | 天天天干天天射天天天操 | 国产精品成人自产拍在线观看 | 天堂网一区二区三区 | 91香蕉久久 | 国产一区二区在线看 | 丁香六月欧美 | 国内毛片毛片 | 久久免费看片 | 国产小视频在线 | 日韩精品免费在线播放 | 国产亚洲成人网 | 天天操天天摸天天爽 | 欧美成人亚洲成人 | 中文字幕一区二区三区在线观看 | 999久久久国产精品 高清av免费观看 | 亚洲视频一区二区三区在线观看 | 欧美国产不卡 | 国产黄色在线观看 | 麻豆视频免费在线播放 | 国产又粗又长又硬免费视频 | 中文字幕在线观看完整版电影 | 九九视频免费在线观看 | 国产精品久久久久久久久久久久久 | 国产精品福利一区 | 成人午夜电影网 | 国产精品福利一区 | 日韩高清在线一区 | 日韩欧美国产成人 | 亚洲视频电影在线 | 精品无人国产偷自产在线 | 久久伦理电影网 | 黄色网www | 欧美精品一区二区性色 | 九九在线高清精品视频 | av色一区| 日韩色一区二区三区 | 91在线精品秘密一区二区 | 国产在线精品二区 | 黄色一区三区 | 美女久久一区 | 亚洲精品字幕 | 狠狠色伊人亚洲综合网站野外 | 亚洲另类人人澡 | 国产精品igao视频网网址 | 99久久精品网 | 国产高清免费在线播放 | 久久爱导航 | 4hu视频 | 国精产品满18岁在线 | 欧美日韩网址 | 狠狠躁夜夜av | 97色在线观看免费视频 | 久青草电影 | 在线视频久久 | 亚洲九九影院 | 欧美一二三区播放 | 亚洲国产网站 | 在线观看的av | 欧美日韩国产在线精品 | 99精品国自产在线 | 探花视频在线观看免费版 | 首页av在线 | 字幕网资源站中文字幕 | 东方av在| 四川妇女搡bbbb搡bbbb搡 | www激情com| 久久亚洲免费 | a√资源在线 | 97视频免费 | 日韩动态视频 | 永久免费的av电影 | 久久综合久久综合这里只有精品 | 亚洲午夜激情网 | 中文字幕在线观看2018 | 日韩免费网址 | 欧美天天干 | 九九视频精品免费 | 久久视频在线观看免费 | 日韩欧美大片免费观看 | 白丝av免费观看 | 中文字幕国产在线 | 狠狠操综合 | 国产又粗又猛又黄视频 | 99re亚洲国产精品 | 国产亚洲激情视频在线 | 91视频在线国产 | 超碰在线公开免费 | 在线看国产视频 | 亚洲精品视频播放 | 久久综合福利 | 中文字幕在线播放一区二区 | 五月天.com | 国产精品免费观看视频 | 欧美一区二视频在线免费观看 | 国产高清免费av | 亚洲在线视频播放 | 久久久www成人免费毛片麻豆 | 91成品人影院 | 欧美a级片网站 | 国产一区二区在线视频观看 | 天天操夜操 | bbw av| 久久精品综合一区 | 国产高清在线一区 | 99riav1国产精品视频 | 男女靠逼app | 视频国产精品 | 97福利视频 | h动漫中文字幕 | 国偷自产中文字幕亚洲手机在线 | 国产理论片在线观看 | 久久成| 黄色小说18 | 亚洲精品乱码久久久久久按摩 | 国内视频1区| 丁香视频全集免费观看 | 亚洲精品一区二区在线观看 | 久久久麻豆精品一区二区 | 国产在线a不卡 | 精品欧美一区二区在线观看 | 成人资源在线 | 91成人欧美 | 日韩午夜三级 | 色婷婷综合久色 | 亚洲精品1区2区3区 超碰成人网 | 最近的中文字幕大全免费版 | 一级黄色在线视频 | 一级黄色片毛片 | 欧美一级高清片 | 黄色国产大片 | 天天拍天天干 | 美女网站色免费 | 亚洲国产免费看 | 九精品| 又黄又爽又刺激的视频 | 亚洲人成人在线 | 天天爽夜夜爽人人爽曰av | 在线观看91久久久久久 | 成人免费视频网站 | 亚洲高清精品在线 | 免费又黄又爽的视频 | 国产精品亚洲a | 97视频在线免费观看 | 97色婷婷 | 17婷婷久久www | 久草观看视频 | 成人h电影 | 久久久久久久免费看 | 97在线视频网站 | 国产中文字幕在线免费观看 | 美女网色| 国产一区欧美一区 | 久久精品草| 中文字幕在线播放av | 草久在线观看视频 | 欧美另类美少妇69xxxx | 精品久久免费 | 成片免费观看视频999 | 久久黄色免费观看 | 久草国产在线观看 | 久久网站av | 亚洲国产精品成人va在线观看 | 免费成人短视频 | 24小时日本在线www免费的 | 九九热在线视频 | 免费观看性生活大片 | 国产一区二区不卡在线 | 黄色美女免费网站 | 日韩久久精品一区二区 | 国产精品免费成人 | 天天干天天干天天操 | av激情五月| 日韩欧美视频在线免费观看 | 亚洲人成影院在线 | 五月婷婷另类国产 | 久久99精品一区二区三区三区 | 又色又爽又黄高潮的免费视频 | 在线日韩三级 | 中文字幕免费一区 | 黄色小说在线免费观看 | 伊人五月天av | 99高清视频有精品视频 | 欧美大片大全 | 国内精品久久久久久久影视简单 | 午夜婷婷在线播放 | 黄色avwww| 香蕉免费在线 | 国内少妇自拍视频一区 | 丝袜+亚洲+另类+欧美+变态 | 久久伦理视频 | 福利一区二区在线 | 免费看黄在线看 | 久久国产欧美日韩精品 | 国产无遮挡又黄又爽在线观看 | 深爱婷婷激情 | 久黄色 | www.天天综合 | 国产999精品视频 | 精品国产一区二区三区男人吃奶 | 91精品久久久久久久91蜜桃 | 2019中文最近的2019中文在线 | 最近高清中文字幕在线国语5 | 国产一区二区三区高清播放 | 中文字幕av在线电影 | 成人av一区二区在线观看 | 在线一级片 | 国内精品中文字幕 | 免费日韩精品 | 国产视频中文字幕 | 亚洲国产网址 | 九热在线| 狠狠色噜噜狠狠狠狠 | 日韩综合第一页 | 精品久久精品久久 | 日韩精品久久久久久久电影99爱 | 国产在线视频导航 | 丁香花在线视频观看免费 | 中文在线字幕免费观 | 日韩精品免费在线观看 | 欧美一进一出抽搐大尺度视频 | 欧美做受高潮1 | 波多野结衣一区 | 亚洲 精品在线视频 | 在线观看你懂的网址 | 国产精品美女在线观看 | 91成年人网站 | 热久久国产精品 | 欧美国产大片 | 久久久久久久久久久影院 | 美女网站黄免费 | 免费看一级黄色大全 | 不卡中文字幕在线 | 日日夜夜爱 | 国产精品久久久久久久久久三级 | 中文字幕乱偷在线 | 久久免费福利视频 | 日韩最新在线视频 | 午夜精品久久久久久99热明星 | 久久久久国 | 日韩剧 | 欧美一级小视频 | 国产麻豆视频免费观看 | 国产精品亚洲成人 | 日韩高清观看 | 国产成人久久精品 | 色综合天 | 亚洲五月激情 | 精品在线播放视频 | 久久国产精品久久国产精品 | 91黄在线看 | 欧美日韩xxx | 免费视频在线观看网站 | a在线观看视频 | 日韩专区中文字幕 | 韩国精品视频在线观看 | 国产丝袜制服在线 | 99精品久久精品一区二区 | 久久这里精品视频 | 国产成人高清在线 | 91视频在线观看免费 | 黄色特级片 | 国产免费高清 | 亚洲有 在线 | 色在线免费视频 | 久久久高清一区二区三区 | 国产一级二级视频 | 色九九影院 | 久久精品免费观看 | 精品福利在线视频 | 亚洲欧美视频网站 | 91精品无人成人www | 亚洲国产美女久久久久 | 欧洲亚洲精品 | 超碰国产97| 一区 二区电影免费在线观看 | 91麻豆文化传媒在线观看 | 色五月成人 | 激情丁香月 | 日韩精品欧美一区 | 人人看人人做人人澡 | 欧美乱码精品一区二区 | 在线亚洲天堂网 | 一区二区三区在线观看 | av片子在线观看 | avlulu久久精品 | 91av在线视频播放 | 成人国产精品免费观看 | www.久久色 | 91女子私密保健养生少妇 | 久久久亚洲网站 | 97人人澡人人添人人爽超碰 | 欧美激精品 | 99 色 | 亚洲精品视频在线播放 | 四虎影视成人精品国库在线观看 | 精品福利av| www.天天干.com | 狠狠色婷婷丁香六月 | 中文字幕在线网址 | 久久不卡视频 | 国产一级电影免费观看 | 欧美日韩aa | 国产亚洲永久域名 | 中中文字幕av | 91尤物国产尤物福利在线播放 | 伊甸园永久入口www 99热 精品在线 | 亚洲第一伊人 | av丝袜天堂 | 九九交易行官网 | 国内精品久久久久久中文字幕 | 中文字幕免费观看视频 | 在线观看成人 | 国产婷婷视频在线 | 亚洲综合激情小说 | 国产999视频在线观看 | 三日本三级少妇三级99 | 日韩精品一区电影 | 免费成人av网站 | 日韩理论片 | 最近日本韩国中文字幕 | 日日夜夜草 | 午夜国产在线观看 | 波多野结衣视频一区二区 | 插综合网 | 在线看av的网址 | 免费看片成年人 | 国产一区二区三区高清播放 | 97人人澡人人爽人人模亚洲 | 五月婷婷狠狠 | 免费看十八岁美女 | 国内精品一区二区 | 久久在线 | 久久三级视频 | www.天天成人国产电影 | 91精品婷婷国产综合久久蝌蚪 | 亚洲极色 | 精品国产99国产精品 | 久久精品久久精品久久精品 | 深爱五月网 | 亚洲欧美婷婷六月色综合 | 亚洲黑丝少妇 | 国产精品女同一区二区三区久久夜 | 日本乱码在线 | 久久欧美视频 | 高清不卡免费视频 | 麻豆免费视频观看 | av资源免费在线观看 | 中文字幕网站 | 韩国av免费在线 | 国产一区黄色 | 91视频在线网址 | 中国一级片免费看 | 97在线观看免费视频 | 六月丁香激情网 | 九九视频这里只有精品 | 亚洲精品激情 | 香蕉在线影院 | 婷婷久草 | 99在线热播精品免费99热 | 久久成人国产精品 | 精品一区二区精品 | 免费观看性生活大片3 | 天天干天天天天 | 国产精品久久久久久久久蜜臀 | 99热这里只有精品国产首页 | 最近在线中文字幕 | 涩涩网站在线 | 国产精品久久久久aaaa九色 | 美女一级毛片视频 | 久久九九影视 | 亚洲狠狠丁香婷婷综合久久久 | 日本久久久久久科技有限公司 | 91精品免费在线 | 在线观看v片 | av资源在线观看 | 五月天堂色 | 91精品国产高清自在线观看 | 99久久精品日本一区二区免费 | 色欧美日韩 | 人人干人人搞 | 91精品国 | 一区三区在线欧 | 国产精品久久久久永久免费看 | 4p变态网欧美系列 | 国产精品久久久久9999 | 在线免费观看麻豆 | 91视频 - 114av | 欧美日韩国产xxx | 国产一区二区在线看 | 日韩精品一区在线播放 | 国产成人高清在线 | 精品国产理论片 | 精品产品国产在线不卡 | 午夜精品久久久久久久久久久久 | 国产成人免费观看久久久 | 高清av影院 | 九九免费在线观看视频 | 中文字幕在线色 | 天天操夜| 亚洲精品视频在 | 狠狠色丁香婷婷综合最新地址 | 免费在线观看成人 | 伊人婷婷在线 | 欧美一区二区视频97 | 高清av中文在线字幕观看1 | 久久久久久久99精品免费观看 | 国产999精品久久久久久 | 欧美久久久久久 | 91av视频免费观看 | 亚洲欧美精品一区 | 中文字幕高清视频 | 欧美日本不卡高清 | 狠狠干婷婷色 | 国产日本亚洲高清 | 久久99深爱久久99精品 | 成片视频在线观看 | 免费视频色 | 91插插视频 | 综合色站导航 | 亚洲精品国产精品乱码在线观看 | 国产私拍在线 | 在线小视频你懂得 | av黄色在线观看 | 激情视频在线高清看 | 欧美性做爰猛烈叫床潮 | 亚洲欧美视频在线观看 | 很污的网站 | 国产一级免费播放 | 国产精品18久久久久久久 | 久草综合在线 | 超碰在线亚洲 | 在线观看国产www | 黄色小说网站在线 | av在线8 | 国产精品麻豆99久久久久久 | 日韩av免费一区二区 | 97超碰人人澡人人 | 色婷婷视频网 | 欧美一级小视频 | 夜夜爽88888免费视频4848 | 99久久999久久久精玫瑰 | 国产精品免费在线 | 久久久综合 | 国产精品s色 | 9999精品视频| 日韩在线观看三区 | 国产高清精品在线观看 | 91免费的视频在线播放 | 国产91免费在线 | 久久精品视频在线免费观看 | 国产偷v国产偷∨精品视频 在线草 | 91精品国产综合久久久久久久 | 欧美精品亚洲二区 | 午夜狠狠干 | 一区免费视频 | 一级黄网| 国产精品一区电影 | 99精品国产一区二区 | 国产69精品久久99不卡的观看体验 | 伊人色综合久久天天 | 在线观看一 | 99资源网| 日韩欧美在线观看一区二区三区 | 亚洲成a人片在线观看网站口工 | 国产精品免费成人 | 香蕉视频网址 | 精品国产人成亚洲区 | 久久久99精品免费观看 | 精品久久免费看 | 免费看日韩片 | 色婷婷九月 | 91久久久国产精品 | 成 人 黄 色 视频播放1 | av免费电影在线 | 亚洲综合精品在线 | 久久久久久久久久福利 | 成人av电影免费 | 国产精品久久影院 | 狠狠狠色丁香综合久久天下网 | 黄色大片网 | 色丁香综合| 天天伊人网 | 国产视频二 | 九九热.com | av不卡免费看 | 午夜国产福利在线 | 国内精品久久久久久久久久久 | 国产精品永久久久久久久久久 | 狠狠躁夜夜a产精品视频 | 天天躁日日躁狠狠躁av麻豆 | 日本黄色大片儿 | 麻豆久久久久久久 | 久久国产精品久久w女人spa | www黄色com| 中文字幕丝袜一区二区 | 国产国产人免费人成免费视频 | 色精品视频 | 狠狠干在线 | 黄污网站在线 | 久久伊人精品一区二区三区 | 四虎www com| 激情五月播播久久久精品 | 在线观看深夜视频 | 免费看国产曰批40分钟 | 日日夜夜国产 | 免费国产视频 | 免费成人av网站 | 夜夜视频欧洲 | 国产精品欧美激情在线观看 | 色噜噜狠狠狠狠色综合 | 国产小视频在线播放 | 欧美激情第28页 | 探花视频免费观看高清视频 | 日韩综合精品 | 亚洲精品美女久久久 | 草久久久 | 国产免费中文字幕 | 久久综合九色综合久99 | 国产精品久久久久永久免费 | 国产精品成人一区二区三区吃奶 | 999久久国产 | 在线国产视频 | 人人干在线观看 | 五月婷婷在线播放 | 99久久婷婷国产精品综合 | 国产成人在线精品 | 亚洲专区 国产精品 | 欧美成人播放 | 中文字幕在线观看网 | 亚洲综合丁香 | 91精品久久久久久综合乱菊 | 免费福利在线 | 国内久久精品视频 | 玖玖爱免费视频 | 日本在线观看视频一区 |