《電子技術(shù)應(yīng)用》
您所在的位置:首頁 > 模擬設(shè)計(jì) > 設(shè)計(jì)應(yīng)用 > 玩轉(zhuǎn)iPhone網(wǎng)絡(luò)通訊之BSD Socket篇
玩轉(zhuǎn)iPhone網(wǎng)絡(luò)通訊之BSD Socket篇
摘要: 在進(jìn)行iPhone網(wǎng)絡(luò)通訊程序的開發(fā)中,不可避免的要利用Socket套接字。iPhone提供了Socket網(wǎng)絡(luò)編程的接口CFSocket,不過筆者更喜歡使用BSDSocket。
Abstract:
Key words :

  在進(jìn)行iPhone網(wǎng)絡(luò)通訊程序的開發(fā)中,不可避免的要利用Socket套接字。iPhone提供了Socket網(wǎng)絡(luò)編程的接口CFSocket,不過筆者更喜歡使用BSD Socket

  iPhone BSD Socket進(jìn)行編程所需要的頭文件基本都位于/Xcode3.1.4/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS3.1.sdk/usr/include/sys下,既然本篇文章作為基礎(chǔ)篇,那么筆者就從最基本的知識(shí)講解開始。

  首先,Socket是進(jìn)行程序間通訊(IPC, Internet Process Connection)的BSD方法,這意味著Socket是用來讓一個(gè)進(jìn)程和其他的進(jìn)程互相通訊的,就像我們用電話來和其他人交流一樣。

  既然說Socket像個(gè)電話,那么如果要打電話首先就要安裝一部電話,“安裝電話”這個(gè)動(dòng)作對(duì)BSD Socket來說就是初始化一個(gè)Socket,方法如下:

  int socket(int, int, int);

  第一個(gè)int參數(shù)為Socket的地址方式,既然要“安裝電話”,那么就要首先確認(rèn)所要安裝的電話是音頻的還是脈沖的。而如果要給BSD Socket安裝電話,有兩種類型可供讀者選擇:AF_UNIX和AF_INET,它們代表Socket的地址格式。如果選擇AF_UNIX,意味著需要為Socket提供一個(gè)類似Unix路徑的名稱,這個(gè)選項(xiàng)主要用于本地程序之間的socket通訊;本文主要講解網(wǎng)絡(luò)通訊,所以需要選擇參數(shù)AF_INET。

  第二個(gè)int參數(shù)為Socket的類型,“安裝電話”需要首先確定是裝有線的還是裝無線的,安裝Socket也一樣,在Socket中提供了兩種類型:SOCK_STREAM和SOCK_DGRAM。SOCK_STREAM表明數(shù)據(jù)像字符流一樣通過Socket;而SOCK_DGRAM則表明數(shù)據(jù)以數(shù)據(jù)報(bào)(Datagrams)的形式通過Socket,本文主要講解SOCK_STREAM,因?yàn)樗氖褂酶鼮閺V泛。

  第三個(gè)int參數(shù)為所使用的協(xié)議,本文里使用0即可。

  “安裝電話”的代碼如下:

  if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)

  {

  perror(“socket”);

  exit(1);

  }

  到現(xiàn)在為止,怎么安裝電話已經(jīng)清楚了。因?yàn)楸疚闹饕菔救绾卧趇Phone上使用BSD Socket獲取內(nèi)容,更多的功能是“打電話”而不是“接電話”,所以下面主要講解BSD Socket扮演“客戶端”角色的操作。

  既然要“打電話”,那么首先要有打電話的對(duì)象,更確切的說需要一個(gè)“電話號(hào)碼”,BSD Socket中的“電話號(hào)碼”就是IP地址。更糟糕的情況是,如果只知道聯(lián)系人的名字而不知道電話號(hào)碼,那么還需要程序查找相應(yīng)聯(lián)系人的電話號(hào)碼,根據(jù)聯(lián)系人姓名查找電話號(hào)碼的過程在BSD Socket中叫做DNS解析,代碼如下:

  - (NSString*)getIpAddressForHost:(NSString*) theHost

  {

  struct hostent *host = gethostbyname([theHost UTF8String]);

  if(!host)

  {

  herror(“resolv”);

  return NULL;

  }

  struct in_addr **list = (struct in_addr **)host-》h_addr_list;

  NSString *addressString = [NSString stringWithCString:inet_ntoa(*list[0])];

  return addressString;

  }

  hostent是個(gè)結(jié)構(gòu)體,使用它需要#import 《netdb.h》,通過這個(gè)方法得到theHost域名的第一個(gè)有效的IP地址并返回。

  正確的“找到電話號(hào)碼”后,就需要“撥打電話”了,代碼如下:

  their_addr.sin_family = AF_INET;

  their_addr.sin_addr.s_addr = inet_addr([[self getIpAddressForHost:hostName] UTF8String]);

  NSLog(@“getIpAddressForHost :%@”,[self getIpAddressForHost:hostName]);

  their_addr.sin_port = htons(80);

  bzero(&(their_addr.sin_zero), 8);

  int conn = connect(sockfd, (struct sockaddr*)&their_addr, sizeof(struct sockaddr));

  NSLog(@“Connect errno is :%d”,conn);

  在進(jìn)行iPhone網(wǎng)絡(luò)通訊程序的開發(fā)中,不可避免的要利用Socket套接字。iPhone提供了Socket網(wǎng)絡(luò)編程的接口CFSocket,不過筆者更喜歡使用BSD Socket。

  iPhone BSD Socket進(jìn)行編程所需要的頭文件基本都位于/Xcode3.1.4/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS3.1.sdk/usr/include/sys下,既然本篇文章作為基礎(chǔ)篇,那么筆者就從最基本的知識(shí)講解開始。

  首先,Socket是進(jìn)行程序間通訊(IPC, Internet Process Connection)的BSD方法,這意味著Socket是用來讓一個(gè)進(jìn)程和其他的進(jìn)程互相通訊的,就像我們用電話來和其他人交流一樣。

  既然說Socket像個(gè)電話,那么如果要打電話首先就要安裝一部電話,“安裝電話”這個(gè)動(dòng)作對(duì)BSD Socket來說就是初始化一個(gè)Socket,方法如下:

  int socket(int, int, int);

  第一個(gè)int參數(shù)為Socket的地址方式,既然要“安裝電話”,那么就要首先確認(rèn)所要安裝的電話是音頻的還是脈沖的。而如果要給BSD Socket安裝電話,有兩種類型可供讀者選擇:AF_UNIX和AF_INET,它們代表Socket的地址格式。如果選擇AF_UNIX,意味著需要為Socket提供一個(gè)類似Unix路徑的名稱,這個(gè)選項(xiàng)主要用于本地程序之間的socket通訊;本文主要講解網(wǎng)絡(luò)通訊,所以需要選擇參數(shù)AF_INET。

  第二個(gè)int參數(shù)為Socket的類型,“安裝電話”需要首先確定是裝有線的還是裝無線的,安裝Socket也一樣,在Socket中提供了兩種類型:SOCK_STREAM和SOCK_DGRAM。SOCK_STREAM表明數(shù)據(jù)像字符流一樣通過Socket;而SOCK_DGRAM則表明數(shù)據(jù)以數(shù)據(jù)報(bào)(Datagrams)的形式通過Socket,本文主要講解SOCK_STREAM,因?yàn)樗氖褂酶鼮閺V泛。

  第三個(gè)int參數(shù)為所使用的協(xié)議,本文里使用0即可。

  “安裝電話”的代碼如下:

  if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)

  {

  perror(“socket”);

  exit(1);

  }

  到現(xiàn)在為止,怎么安裝電話已經(jīng)清楚了。因?yàn)楸疚闹饕菔救绾卧趇Phone上使用BSD Socket獲取內(nèi)容,更多的功能是“打電話”而不是“接電話”,所以下面主要講解BSD Socket扮演“客戶端”角色的操作。

  既然要“打電話”,那么首先要有打電話的對(duì)象,更確切的說需要一個(gè)“電話號(hào)碼”,BSD Socket中的“電話號(hào)碼”就是IP地址。更糟糕的情況是,如果只知道聯(lián)系人的名字而不知道電話號(hào)碼,那么還需要程序查找相應(yīng)聯(lián)系人的電話號(hào)碼,根據(jù)聯(lián)系人姓名查找電話號(hào)碼的過程在BSD Socket中叫做DNS解析,代碼如下:

  - (NSString*)getIpAddressForHost:(NSString*) theHost

  {

  struct hostent *host = gethostbyname([theHost UTF8String]);

  if(!host)

  {

  herror(“resolv”);

  return NULL;

  }

  struct in_addr **list = (struct in_addr **)host-》h_addr_list;

  NSString *addressString = [NSString stringWithCString:inet_ntoa(*list[0])];

  return addressString;

  }

  hostent是個(gè)結(jié)構(gòu)體,使用它需要#import 《netdb.h》,通過這個(gè)方法得到theHost域名的第一個(gè)有效的IP地址并返回。

  正確的“找到電話號(hào)碼”后,就需要“撥打電話”了,代碼如下:

  their_addr.sin_family = AF_INET;

  their_addr.sin_addr.s_addr = inet_addr([[self getIpAddressForHost:hostName] UTF8String]);

  NSLog(@“getIpAddressForHost :%@”,[self getIpAddressForHost:hostName]);

  their_addr.sin_port = htons(80);

  bzero(&(their_addr.sin_zero), 8);

  int conn = connect(sockfd, (struct sockaddr*)&their_addr, sizeof(struct sockaddr));

  NSLog(@“Connect errno is :%d”,conn);

  筆者最初試圖采用NHost進(jìn)行主機(jī)域名的解析,奈何iPhone的這個(gè)類為private的,在application的開發(fā)中不可使用。

  如果“電話”能順利的接通,那么就可以進(jìn)行“講話”了,反之則會(huì)斷開“電話連接”,如果友好的話,最好能給個(gè)提示,諸如“您所撥打的電話不在服務(wù)區(qū)之類”:)

  if(conn != -1)

  {

  NSLog(@“Then the conn is not -1!”);

  NSMutableString* httpContent = [self makeHttpHeader:hostName];

  NSLog(@“httpCotent is :%@”,httpContent);

  if(contentSended != nil)

  [httpContent appendFormat:contentSended];

  NSLog(@“Sended content is :%@”,httpContent);

  NSData *data = [httpContent dataUsingEncoding:NSISOLatin1StringEncoding];

  ssize_t dataSended = send(sockfd, [data bytes], [data length], 0);

  if(dataSended == [data length])

  {

  NSLog(@“Datas have been sended over!”);

  }

  printf(“send %d bytes to %s\n”,dataSended,inet_ntoa(their_addr.sin_addr));

  NSMutableString* readString = [[NSMutableString alloc] init];

  char readBuffer[512];

  int br = 0;

  while((br = recv(sockfd, readBuffer, sizeof(readBuffer), 0)) 《 sizeof(readBuffer))

  {

  NSLog(@“read datas length is :%d”,br);

  [readString appendFormat:[NSString stringWithCString:readBuffer length:br]];

  NSLog(@“Hava received datas is :%@”,readString);

  }

  close(sockfd);

  }else {

  UIAlertView *alert = [[UIAlertView alloc] initWithTitle:[@“Connection failed to host ” stringByAppendingString:hostName] message:@“Please check the hostname in the preferences.” delegate:self cancelButtonTitle:@“OK” otherButtonTitles:nil];

  [alert show];

  [alert release];

  }

  “講話”通過send(),“聽話”通過recv(),這個(gè)兩個(gè)函數(shù)的原型如下:

  int send(int sockfd, const void *msg, int len, int flags);

  int recv(int sockfd,void *buf,int len,unsigned int flags);

  可以看出,這兩個(gè)函數(shù)的參數(shù)基本相同。

  第一個(gè)參數(shù)為套接字的句柄。

  第二個(gè)參數(shù)為數(shù)據(jù)緩沖區(qū)。

  第三個(gè)參數(shù)為數(shù)據(jù)長度。

  最后一個(gè)參數(shù)有點(diǎn)特殊,這個(gè)參數(shù)是為了讓BSD Socket能支持“帶外數(shù)據(jù)”,何謂“帶外數(shù)據(jù)”?顧名思義,就是“帶內(nèi)以外的數(shù)據(jù)”,而帶內(nèi)數(shù)據(jù)就是常規(guī)的按照Socket字節(jié)流順序進(jìn)行傳遞的數(shù)據(jù)。通常情況下,數(shù)據(jù)由連接的一端流到接收的一端,并且認(rèn)為數(shù)據(jù)的所有字節(jié)都是精確排序的,晚寫入的字節(jié)絕不會(huì)早于先寫入的字節(jié)到達(dá)。但是如果我們“掛斷了電話”,而接收方還有大量已經(jīng)被接收的緩沖數(shù)據(jù),這些數(shù)據(jù)還沒被程序讀取,那么接收方需要在讀取這些緩沖的“帶內(nèi)數(shù)據(jù)”之前先讀取一個(gè)標(biāo)識(shí)取消的請(qǐng)求,這個(gè)請(qǐng)求就可以利用帶外請(qǐng)求的方法進(jìn)行傳送。請(qǐng)求帶外數(shù)據(jù)傳送需要把標(biāo)識(shí)位置為MSG_OOB,如下:

  char buf[64];

  int len;

  int s;

  …

  send(s,buf,len,MSG_OOB);

  至此,一個(gè)完整的“通話過程”已經(jīng)結(jié)束,最后別忘記調(diào)用close(sockfd)“掛斷電話”。

  下面筆者嘗試請(qǐng)求www.baidu.com的首頁,并把請(qǐng)求的頁面內(nèi)容打印到控制臺(tái),所以需要對(duì)請(qǐng)求進(jìn)行封裝,以支持HTTP協(xié)議。很簡單,只需要在請(qǐng)求的內(nèi)容前面加上相應(yīng)的HTTP頭信息即可,如下:

  #define HTTPMETHOD @“GET”

  #define HTTPVERSION @“HTTP/1.1”

  #define HTTPHOST @“Host”

  #define KENTER @“\r\n”

  #define KBLANK @“ ”

  - (NSMutableString*) makeHttpHeader:(NSString*) hostName

  {

  NSMutableString *header = [[NSMutableString alloc] init];

  [header appendFormat:HTTPMETHOD];

  [header appendFormat:KBLANK];

  [header appendFormat:@“/index.html”];

  [header appendFormat:KBLANK];

  [header appendFormat:HTTPVERSION];

  [header appendFormat:KENTER];

  [header appendFormat:HTTPHOST];

  [header appendFormat:@“:”];

  [header appendFormat:hostName];

  [header appendFormat:KENTER];

  [header appendFormat:KENTER];

  return header;

  }

  在上面的方法中,筆者封裝了HTTP頭信息,對(duì)HTTP不熟悉的同學(xué)可以先熟悉熟悉HTTP的格式,請(qǐng)求到的內(nèi)容打印如下:

  [Session started at 2009-11-12 15:40:02 +0800.]

  2009-11-12 15:40:04.691 BSDHttpExample[3483:207] getIpAddressForHost :119.75.216.30

  2009-11-12 15:40:04.725 BSDHttpExample[3483:207] Connect errno is :0

  2009-11-12 15:40:04.727 BSDHttpExample[3483:207] Then the conn is not -1!

  2009-11-12 15:40:04.735 BSDHttpExample[3483:207] httpCotent is :GET /index.html HTTP/1.1

  Host:www.baidu.com

  2009-11-12 15:40:04.736 BSDHttpExample[3483:207] Sended content is :GET /index.html HTTP/1.1

  Host:www.baidu.com

  2009-11-12 15:40:04.736 BSDHttpExample[3483:207] Datas have been sended over!

  send 48 bytes to 119.75.216.30

  2009-11-12 15:40:04.764 BSDHttpExample[3483:207] read datas length is :363

  2009-11-12 15:40:04.765 BSDHttpExample[3483:207] Hava received datas is :HTTP/1.1 200 OK

  Date: Thu, 12 Nov 2009 07:40:05 GMT

  Server: BWS/1.0

  Content-Length: 3520

  Content-Type: text/html;charset=gb2312

  Cache-Control: private

  Expires: Thu, 12 Nov 2009 07:40:05 GMT

  Set-Cookie: BAIDUID=9B024266ADD3B52AC8367A2BDD1676E5:FG=1; expires=Thu, 12-Nov-39 07:40:05 GMT; path=/; domain=.baidu.com

  P3P: CP=“ OTI DSP COR IVA OUR IND COM ”

  2009-11-12 15:40:04.766 BSDHttpExample[3483:207] view has been loaded!

  最后為了造福大家,筆者附上完整的代碼,頭文件如下:

  //

  // BSDHttpExampleViewController.h

  // BSDHttpExample

  //

  // Created by sun dfsun2009 on 09-11-12.

  // Copyright __MyCompanyName__ 2009. All rights reserved.

  //

  #import 《UIKit/UIKit.h》

  #define MYPORT 4880

  #import 《stdio.h》

  #import 《stdlib.h》

  #import 《unistd.h》

  #import 《arpa/inet.h》

  #import 《sys/types.h》

  #import 《sys/socket.h》

  #import 《netdb.h》

  @interface BSDHttpExampleViewController : UIViewController {

  int sockfd;

  struct sockaddr_in their_addr;

  }

  @end

  實(shí)現(xiàn)文件如下:

  //

  // BSDHttpExampleViewController.m

  // BSDHttpExample

  //

  // Created by sun dfsun2009 on 09-11-12.

  // Copyright __MyCompanyName__ 2009. All rights reserved.

  //

  #import “BSDHttpExampleViewController.h”

  @implementation BSDHttpExampleViewController

  #define HTTPMETHOD @“GET”

  #define HTTPVERSION @“HTTP/1.1”

  #define HTTPHOST @“Host”

  #define KENTER @“\r\n”

  #define KBLANK @“ ”

  /*

  // The designated initializer. Override to perform setup that is required before the view is loaded.

  - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {

  if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {

  // Custom initialization

  }

  return self;

  }

  */

  /*

  // Implement loadView to create a view hierarchy programmatically, without using a nib.

  - (void)loadView {

  }

  */

  void error_handle(char *errorMsg)

  {

  fputs(errorMsg, stderr);

  fputc(‘\n’,stderr);

  exit(1);

  }

  - (NSMutableString*) makeHttpHeader:(NSString*) hostName

  {

  NSMutableString *header = [[NSMutableString alloc] init];

  [header appendFormat:HTTPMETHOD];

  [header appendFormat:KBLANK];

  [header appendFormat:@“/index.html”];

  [header appendFormat:KBLANK];

  [header appendFormat:HTTPVERSION];

  [header appendFormat:KENTER];

  [header appendFormat:HTTPHOST];

  [header appendFormat:@“:”];

  [header appendFormat:hostName];

  [header appendFormat:KENTER];

  [header appendFormat:KENTER];

  return header;

  }

  - (NSString*)getIpAddressForHost:(NSString*) theHost

  {

  struct hostent *host = gethostbyname([theHost UTF8String]);

  if(!host)

  {

  herror(“resolv”);

  return NULL;

  }

  struct in_addr **list = (struct in_addr **)host-》h_addr_list;

  NSString *addressString = [NSString stringWithCString:inet_ntoa(*list[0])];

  return addressString;

  }

  - (void)Connect:(NSString *)hostName content:(NSString *)contentSended

  {

  if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)

  {

  perror(“socket”);

  exit(1);

  }

  //NSHost *host = [NSHost hostWithName:hostName];

  //if(host)

  //{

  their_addr.sin_family = AF_INET;

  //their_addr.sin_addr.s_addr = inet_addr([[host address] UTF8String]);

  their_addr.sin_addr.s_addr = inet_addr([[self getIpAddressForHost:hostName] UTF8String]);

  NSLog(@“getIpAddressForHost :%@”,[self getIpAddressForHost:hostName]);

  their_addr.sin_port = htons(80);

  bzero(&(their_addr.sin_zero), 8);

  int conn = connect(sockfd, (struct sockaddr*)&their_addr, sizeof(struct sockaddr));

  NSLog(@“Connect errno is :%d”,conn);

  if(conn != -1)

  {

  NSLog(@“Then the conn is not -1!”);

  NSMutableString* httpContent = [self makeHttpHeader:hostName];

  NSLog(@“httpCotent is :%@”,httpContent);

  if(contentSended != nil)

  [httpContent appendFormat:contentSended];

  NSLog(@“Sended content is :%@”,httpContent);

  NSData *data = [httpContent dataUsingEncoding:NSISOLatin1StringEncoding];

  ssize_t dataSended = send(sockfd, [data bytes], [data length], 0);

  if(dataSended == [data length])

  {

  NSLog(@“Datas have been sended over!”);

  }

  printf(“send %d bytes to %s\n”,dataSended,inet_ntoa(their_addr.sin_addr));

  NSMutableString* readString = [[NSMutableString alloc] init];

  char readBuffer[512];

  int br = 0;

  while((br = recv(sockfd, readBuffer, sizeof(readBuffer), 0)) 《 sizeof(readBuffer))

  {

  NSLog(@“read datas length is :%d”,br);

  [readString appendFormat:[NSString stringWithCString:readBuffer length:br]];

  NSLog(@“Hava received datas is :%@”,readString);

  }

  close(sockfd);

  }else {

  UIAlertView *alert = [[UIAlertView alloc] initWithTitle:[@“Connection failed to host ” stringByAppendingString:hostName] message:@“Please check the hostname in the preferences.” delegate:self cancelButtonTitle:@“OK” otherButtonTitles:nil];

  [alert show];

  [alert release];

  }

  /*

  }

  else

  {

  UIAlertView *alert = [[UIAlertView alloc] initWithTitle:[@“Could not look up host ” stringByAppendingString:hostName] message:@“Please check the hostname in the preferences.” delegate:self cancelButtonTitle:@“OK” otherButtonTitles:nil];

  [alert show];

  [alert release];

  }

  **/

  }

  - (void)Send:(id)sender

  {

  char message[7] = “aaag”;

  send(sockfd,message,sizeof(message),0);

  NSLog(@“%s”,message);

  }

  // Implement viewDidLoad to do additional setup after loading the view, typically from a nib.

  - (void)viewDidLoad {

  [self Connect:@“www.baidu.com” content:nil];

  [super viewDidLoad];

  NSLog(@“view has been loaded!”);

  }

  /*

  // Override to allow orientations other than the default portrait orientation.

  - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {

  // Return YES for supported orientations

  return (interfaceOrientation == UIInterfaceOrientationPortrait);

  }

  */

  - (void)didReceiveMemoryWarning {

  // Releases the view if it doesn‘t have a superview.

  [super didReceiveMemoryWarning];

  // Release any cached data, images, etc that aren’t in use.

  }

  - (void)viewDidUnload {

  // Release any retained subviews of the main view.

  // e.g. self.myOutlet = nil;

  }

  - (void)dealloc {

  [super dealloc];

  }

  @end

此內(nèi)容為AET網(wǎng)站原創(chuàng),未經(jīng)授權(quán)禁止轉(zhuǎn)載。
亚洲一区二区欧美_亚洲丝袜一区_99re亚洲国产精品_日韩亚洲一区二区
欧美人在线视频| 在线观看一区欧美| 欧美成人国产va精品日本一级| 亚洲免费中文字幕| 一区二区高清视频| 亚洲精品在线观看视频| 亚洲国产欧美一区二区三区同亚洲 | 亚洲女女女同性video| 中日韩午夜理伦电影免费| 一本到12不卡视频在线dvd| 亚洲美女啪啪| 日韩一级大片在线| 99视频精品全国免费| 亚洲精品少妇30p| 一区二区久久| 亚洲视频axxx| 午夜精品视频在线| 久久精品国产亚洲一区二区| 久久久久久久综合日本| 久久综合五月| 欧美国产日韩二区| 欧美日韩国产免费观看| 欧美视频在线观看免费| 国产精品国产三级欧美二区| 国产精品男女猛烈高潮激情| 国产精品日韩欧美一区| 国产欧美亚洲一区| 国产自产在线视频一区| 在线不卡欧美| 亚洲免费观看| 亚洲一区自拍| 久久国产精品99国产精| 亚洲精品国偷自产在线99热| 一本色道久久加勒比88综合| 亚洲综合色在线| 欧美一区国产二区| 久久女同互慰一区二区三区| 麻豆成人在线观看| 欧美日韩亚洲一区二区三区在线| 国产精品看片资源| 国产欧美一区二区精品仙草咪| 国产午夜精品麻豆| 亚洲国产欧美一区| 日韩午夜电影| 香蕉乱码成人久久天堂爱免费| 久久精品五月| 99这里只有久久精品视频| 亚洲欧美日韩区| 蜜臀av国产精品久久久久| 欧美人在线视频| 国产欧美一区二区精品性色| 激情另类综合| 一区二区三区高清在线| 性欧美精品高清| 亚洲精品一区二区在线观看| 午夜精品影院| 狂野欧美激情性xxxx欧美| 欧美日韩三级一区二区| 国产一区 二区 三区一级| 亚洲精品系列| 欧美一区二区三区喷汁尤物| 99精品久久| 久久成人免费电影| 欧美激情一区二区三区蜜桃视频| 国产精品三级久久久久久电影| 在线日韩精品视频| 国产精品99久久久久久人| 欧美一区二区成人| 一个色综合av| 久久综合久久综合九色| 国产精品大片| 亚洲电影在线观看| 午夜精品美女久久久久av福利| 亚洲乱码日产精品bd| 久久久久9999亚洲精品| 欧美三级电影一区| 在线国产日韩| 午夜激情久久久| 一区二区三区免费网站| 久久噜噜亚洲综合| 欧美三区美女| 亚洲高清不卡| 午夜性色一区二区三区免费视频| 亚洲美女av网站| 久久嫩草精品久久久精品| 国产精品国产三级国产| 亚洲国产女人aaa毛片在线| 性久久久久久久| 亚洲综合欧美日韩| 欧美久久久久久蜜桃| 在线播放豆国产99亚洲| 性欧美1819性猛交| 亚洲综合视频一区| 欧美日韩视频在线第一区| 亚洲国产精品成人| 久久精品导航| 久久成年人视频| 欧美午夜视频| 日韩亚洲视频在线| 91久久久久久| 美女黄网久久| 在线电影国产精品| 久久激情一区| 久久精品亚洲精品| 国产精品一卡二| 亚洲夜间福利| 亚洲一区二区免费看| 欧美激情一区在线| 亚洲日本视频| 亚洲伦伦在线| 欧美本精品男人aⅴ天堂| 精品成人乱色一区二区| 久久精品国产免费观看| 久久久久免费视频| 国外成人免费视频| 亚洲大黄网站| 美女国产精品| 亚洲国产精品成人| 亚洲乱码国产乱码精品精可以看| 欧美高清在线视频| 亚洲人精品午夜| 一本一本久久| 欧美色另类天堂2015| 一本色道久久综合亚洲精品按摩 | 亚洲人成亚洲人成在线观看图片| 亚洲国产日韩欧美综合久久| 免费人成网站在线观看欧美高清| 激情婷婷亚洲| 亚洲激情一区二区三区| 欧美国产精品劲爆| 亚洲免费高清视频| 亚洲伊人伊色伊影伊综合网| 国产精品久久波多野结衣| 亚洲午夜免费福利视频| 亚洲欧美精品伊人久久| 国产欧美一区二区三区在线老狼 | 欧美性猛交视频| 亚洲综合精品| 欧美在线999| 国内精品久久久久伊人av| 亚洲国产欧美久久| 欧美日韩成人| 亚洲一区在线免费观看| 久久久五月天| 亚洲国产天堂久久综合网| 中国女人久久久| 国产精品午夜在线观看| 久久国产一区二区| 欧美精品久久久久久久久老牛影院| 一级成人国产| 久久99在线观看| 在线观看日韩专区| 中日韩在线视频| 国产麻豆综合| 亚洲电影av| 欧美日本中文字幕| 亚洲欧美精品一区| 狂野欧美激情性xxxx| 亚洲美女91| 久久er精品视频| 亚洲福利视频免费观看| 中文一区二区在线观看| 国产亚洲一区在线| 99精品免费视频| 国产日产精品一区二区三区四区的观看方式 | 午夜精品婷婷| 影视先锋久久| 亚洲天天影视| 国内免费精品永久在线视频| av成人毛片| 国产亚洲精品激情久久| 亚洲理伦在线| 国产视频精品va久久久久久| 亚洲精品乱码久久久久| 国产精品国产a级| 亚洲国产人成综合网站| 国产精品不卡在线| 亚洲国产一区二区三区青草影视 | 午夜欧美大片免费观看| 在线欧美不卡| 香蕉精品999视频一区二区| 亚洲国产精品va| 欧美在线首页| 99视频精品免费观看| 久久综合久久久久88| 亚洲一区二区三区乱码aⅴ| 免费观看久久久4p| 性娇小13――14欧美| 欧美日韩一区二区高清| 亚洲成人在线视频网站| 国产精品嫩草99a| 99亚洲视频| 黄页网站一区| 欧美亚洲一区二区三区| 亚洲精品视频免费在线观看| 久久亚洲不卡| 午夜在线观看免费一区| 欧美日韩在线视频一区二区| 亚洲国产激情| 国产一区二区高清不卡|