456成人影院在线观看_亚洲a毛片_日韩9999_伊人网老司机_一本免费视频_最近高清日本免费

IT之道-艾銻知道

您當前位置: 主頁 > IT服務 > 網絡服務 >

網絡技術編程之多線程服務器端的實現


2015-10-28 08:48 作者:admin 瀏覽量:

  線程的創建和上下文切換開銷更小且速度更快。(網絡外包公司

  線程間交換數據時無需特殊技術。

  進程:在操作系統構成單獨執行流的單位。

  線程:在進程構成單獨執行流的單位。

  它們的包含關系是,操作系統 > 進程 > 線程。進程與線程具體差異其實是這樣的,每個進程都有獨立的完整內存空間,它包括全局數據區,堆區,棧區,而多進程服務器之所以開銷大是因為只是為了區分棧區里的不同函數流執行而把數據區,堆區,棧區內存全部復制了一份。而多線程就高效多了,它只把棧區分離出來,進程中的數據區,堆區則共享。具體內存結構示例圖如下:

  線程創建及運行

  線程具有單獨的執行流,因此需要單獨定義線程的入口函數,而且還需要請求操作系統在單獨的執行流中執行該函數,完成這個功能的函數如下:

  #include int pthread_create( pthread_t * restrict thread,//保存線程ID const pthread_attr_t * restrict attr,//線程屬性,NULL默認屬性 void * (* start_routine)(void *), //線程入口函數,函數指針 void * restrict arg //傳遞給入口函數的參數 );

  實例代碼:

  #include #include #include void * thread_main(void *arg); int main(int argc, char *argv[]) { pthread_t t_id; int thread_param = 5; if (pthread_create(&t_id, NULL, thread_main, (void *)&thread_param) != 0) { puts("pthread_create() error"); return -1; } sleep(10); puts("end of main"); return 0; } void * thread_main(void *arg) { int i; int cnt =* ((int *)arg); for (i = 0; i < cnt; i++) { sleep(1); puts("running thread"); } return NULL; }

  

TCP/IP網絡編程 多線程服務器端的實現

  上面實例是用sleep延遲來控制線程的執行的,如果主線程不做延遲那么執行到return 0;時,進程就結束了,相應的線程也會銷毀。而明顯用sleep這種方式控制線程執行流是不合理的,下面我們來看看一個更好的延遲函數,調用該函數的進程(或線程)將進入等待狀態,直到第一個參數為ID的線程終止為止。而且可以得到線程的入口函數返回值。(IT外包

  #include int pthread_join(pthread_t thread, void **status); 參數1:線程ID 參數2:保存線程入口函數的返回值

  實例代碼:

  #include #include #include #include void * thread_main(void *arg); int main(int argc, char *argv[]) { pthread_t t_id; int thread_param = 5; void * thr_ret; //創建線程 if (pthread_create(&t_id, NULL, thread_main, (void *)&thread_param) != 0) { puts("pthread_create() error"); return -1; } //等待線程返回 if (pthread_join(t_id, &thr_ret) != 0) { puts("pthread_join() error"); return -1; } printf("Thread return message: %s \n", (char *)thr_ret); free(thr_ret); return 0; } //線程入口函數 void * thread_main(void *arg) { int i; int cnt =* ((int *)arg); char * msg = (char *)malloc(sizeof(char) * 50); strcpy(msg, "Hello, I am thread ~ \n"); for (i = 0; i < cnt; i++) { puts("running thread"); } return (void *)msg; }

TCP/IP網絡編程 多線程服務器端的實現

  線程存在的問題和臨界區

  前面我們知道了怎么創建線程,但我們都是只創建了一個線程,下面我們再來看看這樣一個實例,創建100個線程,它們都訪問了同一變量,其中一半對這個變量進行加1操作,一半進行減1操作,按道理其結果會等于0.

  #include #include #include #include #define NUM_THREAD 100 void * thread_inc(void * arg); void * thread_des(void * arg); long long num = 0; //long long類型是64位整數型,多線程共同訪問 int main(int argc, char *argv[]) { pthread_t thread_id[NUM_THREAD]; int i; //創建100個線程,一半執行thread_inc,一半執行thread_des for(i = 0; i < NUM_THREAD; i++) { if(i %2) pthread_create(&(thread_id[i]), NULL, thread_inc, NULL); else pthread_create(&(thread_id[i]), NULL, thread_des, NULL); } //等待線程返回 for (i = 0; i < NUM_THREAD; i++) pthread_join(thread_id[i], NULL); printf("result: %lld \n", num); //+1,-1按道理結果是0 return 0; } //線程入口函數1 void * thread_inc(void * arg) { for (int i = 0; i < 50000000; i++) num += 1;//臨界區(引起問題的語句就是臨界區位置) return NULL; } //線程入口函數2 void * thread_des(void * arg) { for (int i = 0; i < 50000000; i++) num -= 1;//臨界區 return NULL; }

TCP/IP網絡編程 多線程服務器端的實現

  從運行結果看并不是0,而且每次運行的結果都不同。那這是什么原因引起的呢? 是因為每個線程訪問一個變量是這樣一個過程:先從內存取出這個變量值到CPU,然后CPU計算得到改變后的值,最后再將這個改變后的值寫回內存。因此,我們可以很容易看出,多個線程訪問同一變量,如果某個線程還只剛從內存取出數據,還沒來得及寫回內存,這時其它線程又訪問了這個變量,所以這個值就會不正確了。

  接下來我們再來講講怎么解決這個問題:線程同步

  線程同步

  線程同步用于解決線程訪問順序引發的問題,一般是如下兩種情況:

  同時訪問同一內存空間時發生的情況

  需要指定訪問同一內存空間的線程執行順序的情況

  針對這兩種可能引發的情況,我們分別使用的同步技術是:互斥量和信號量。

  互斥量

  互斥量技術從字面也可以理解,就是臨界區有線程訪問,其它線程就得排隊等待,它們的訪問是互斥的,實現方式就是給臨界區加鎖與釋放鎖。

  #include int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr); //創建互斥量 int pthread_mutex_destroy(pthread_mutex_t *mutex);//銷毀互斥量 int pthread_mutex_lock(pthread_mutex_t *mutex);//加鎖 int pthread_mutex_unlock(pthread_mutex_t *mutex);//釋放鎖

  簡言之,就是利用lock和unlock函數圍住臨界區的兩端。當某個線程調用pthread_mutex_lock進入臨界區后,如果沒有調用pthread_mutex_unlock釋放鎖退出,那么其它線程就會一直阻塞在臨界區之外,我們把這種情況稱之為死鎖。所以臨界區圍住一定要lock和unlock一一對應。

  實例代碼:

  #include #include #include #include #define NUM_THREAD 100 void * thread_inc(void * arg); void * thread_des(void * arg); long long num = 0; pthread_mutex_t mutex; int main(int argc, char *argv[]) { pthread_t thread_id[NUM_THREAD]; int i; //互斥量的創建 pthread_mutex_init(&mutex, NULL); for(i = 0; i < NUM_THREAD; i++) { if(i %2) pthread_create(&(thread_id[i]), NULL, thread_inc, NULL); else pthread_create(&(thread_id[i]), NULL, thread_des, NULL); } for (i = 0; i < NUM_THREAD; i++) pthread_join(thread_id[i], NULL); printf("result: %lld \n", num); pthread_mutex_destroy(&mutex); //互斥量的銷毀 return 0; } /*擴展臨界區,減少加鎖,釋放鎖調用次數,但這樣變量必須加滿到50000000次后其它線程才能訪問. 這樣是延長了線程的等待時間,但縮短了加鎖,釋放鎖函數調用的時間,這里沒有定論,自己酌情考慮*/ void * thread_inc(void * arg) { pthread_mutex_lock(&mutex); //互斥量鎖住 for (int i = 0; i < 1000000; i++) num += 1; pthread_mutex_unlock(&mutex); //互斥量釋放鎖 return NULL; } /*縮短了線程等待時間,但循環創建,釋放鎖函數調用時間增加*/ void * thread_des(void * arg) { for (int i = 0; i < 1000000; i++) { pthread_mutex_lock(&mutex); num -= 1; pthread_mutex_unlock(&mutex); } return NULL; }

TCP/IP網絡編程 多線程服務器端的實現

  信號量

  信號量與互斥量類似,只是互斥量是用鎖來控制線程訪問而信號量是用二進制0,1來完成控制線程順序。sem_post信號量加1,sem_wait信號量減1,當信號量為0時,sem_wait就會阻斷,因此通過這樣讓信號量加1減1就能控制線程的執行順序了。

  注釋:mac上測試信號量函數返回-1失敗,以后還是Linux上整吧,也許這些接口已經過時了…

  #include int sem_init(sem_t *sem, int pshared, unsigned int value);//創建信號量 int sem_destroy(sem_t *sem);//銷毀信號量 int sem_post(sem_t *sem);//信號量加1 int sem_wait(sem_t *sem);//信號量減1,為0時阻塞

  實例代碼:線程A從用戶輸入得到值后存入全局變量num,此時線程B將取走該值并累加。該過程共進行5次,完成后輸出總和并退出程序。

  #include #include #include void * read(void * arg); void * accu(void * arg); static sem_t sem_one; static sem_t sem_two; static int num; int main(int argc, char *argv[]) { pthread_t id_t1, id_t2; sem_init(&sem_one, 0, 0); sem_init(&sem_two, 0, 1); pthread_create(&id_t1, NULL, read, NULL); pthread_create(&id_t2, NULL, accu, NULL); pthread_join(id_t1, NULL); pthread_join(id_t2, NULL); sem_destroy(&sem_one); sem_destroy(&sem_two); return 0; } void * read(void * arg) { int i; for (i = 0; i < 5; i++) { fputs("Input num: ", stdout); sem_wait(&sem_two); scanf("%d", &num); sem_post(&sem_one); } return NULL; } void * accu(void * arg) { int sum = 0 , i; for (i = 0; i < 5; i++) { sem_wait(&sem_one); sum+= num; sem_post(&sem_two); } printf("Result: %d \n", sum); return NULL; }

  補充:線程的銷毀,線程創建后并不是其入口函數返回后就會自動銷毀,需要手動銷毀,不然線程創建的內存空間將一直存在。一般手動銷毀有如下兩種方式:1,調用pthread_join函數,其返回后同時銷毀線程 ,是一個阻斷函數,服務端一般不用它銷毀,因為服務端主線程不宜阻斷,還要實時監聽客服端連接。2,調用pthread_detach函數,不會阻塞,線程返回自動銷毀線程,不過要注意調用它后不能再調用pthread_join函數,它與pthread_join主要區別就是一個是阻塞函數,一個不阻塞。

  多線程并發服務端的實現

  使用多線程實現了一個簡單的聊天程序,并對臨界區(clnt_cnt,clnt_socks)進行加鎖訪問.

  服務端:

  // // main.cpp // hello_server // // Created by app05 on 15-10-22. // Copyright (c) 2015年 app05. All rights reserved. //臨界區是:clnt_cnt和clnt_socks訪問處 #include #include #include #include #include #include #include #define BUF_SIZE 100 #define MAX_CLNT 256 void * handle_clnt(void * arg); void send_msg(char *msg, int len); void error_handling(char * msg); int clnt_cnt = 0; int clnt_socks[MAX_CLNT]; pthread_mutex_t mutx; int main(int argc, char *argv[]) { int serv_sock, clnt_sock; struct sockaddr_in serv_adr, clnt_adr; socklen_t clnt_adr_sz; pthread_t t_id; if (argc != 2) { printf("Usage : %s \n", argv[0]); exit(1); } //創建互斥量 pthread_mutex_init(&mutx, NULL); serv_sock = socket(PF_INET, SOCK_STREAM, 0); memset(&serv_adr, 0, sizeof(serv_adr)); serv_adr.sin_family = AF_INET; serv_adr.sin_addr.s_addr = htonl(INADDR_ANY); serv_adr.sin_port = htons(atoi(argv[1])); if(bind(serv_sock, (struct sockaddr *) &serv_adr, sizeof(serv_adr)) == -1) error_handling("bind() error"); if(listen(serv_sock, 5) == -1) error_handling("listen() error"); while (1) { clnt_adr_sz = sizeof(clnt_adr); clnt_sock = accept(serv_sock, (struct sockaddr*)&clnt_adr, &clnt_adr_sz); //阻斷,監聽客服端連接請求 //臨界區 pthread_mutex_lock(&mutx); //加鎖 clnt_socks[clnt_cnt++] = clnt_sock; //新連接的客服端保存到clnt_socks數組里 pthread_mutex_unlock(&mutx); //釋放鎖 //創建線程 pthread_create(&t_id, NULL, handle_clnt, (void*) &clnt_sock); pthread_detach(t_id); //銷毀線程,線程return后自動調用銷毀,不阻斷 printf("Connected client IP: %s \n", inet_ntoa(clnt_adr.sin_addr)); } close(serv_sock); return 0; } //線程執行 void * handle_clnt(void * arg) { int clnt_sock = *((int *)arg); int str_len = 0, i; char msg[BUF_SIZE]; while ((str_len = read(clnt_sock, msg, sizeof(msg))) != 0) send_msg(msg, str_len); //從數組中移除當前客服端 pthread_mutex_lock(&mutx); for (i = 0; i < clnt_cnt; i++) { if (clnt_sock == clnt_socks[i]) { while (i++ < clnt_cnt - 1) clnt_socks[i] = clnt_socks[i + 1]; break; } } clnt_cnt--; pthread_mutex_unlock(&mutx); close(clnt_sock); return NULL; } //向所有連接的客服端發送消息 void send_msg(char * msg, int len) { int i; pthread_mutex_lock(&mutx); for (i = 0; i < clnt_cnt; i++) write(clnt_socks[i], msg, len); pthread_mutex_unlock(&mutx); } void error_handling(char *message) { fputs(message, stderr); fputc('\n', stderr); exit(1); }

  客服端

  // // main.cpp // hello_client // // Created by app05 on 15-10-22. // Copyright (c) 2015年 app05. All rights reserved. // // #include #include #include #include #include #include #include #define BUF_SIZE 100 #define NAME_SIZE 20 void * send_msg(void * arg); void * recv_msg(void * arg); void error_handling(char *message); char name[NAME_SIZE] = "[DEFAULT]"; char msg[BUF_SIZE]; int main(int argc, const char * argv[]) { int sock; struct sockaddr_in serv_addr; pthread_t snd_thread, rcv_thread; void * thread_return; if(argc != 4) { printf("Usage: %s \n", argv[0]); exit(1); } sprintf(name, "[%s]", argv[3]); //聊天人名字,配置到編譯器參數里 sock = socket(PF_INET, SOCK_STREAM, 0); if(sock == -1) error_handling("socket() error"); memset(&serv_addr, 0, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = inet_addr(argv[1]); serv_addr.sin_port = htons(atoi(argv[2])); if (connect(sock, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) == -1) error_handling("connect() error"); //多線程分離輸入和輸出 (北京it外包公司)pthread_create(&snd_thread, NULL, send_msg, (void *)&sock); pthread_create(&rcv_thread, NULL, recv_msg, (void *)&sock); //阻塞,等待返回 pthread_join(snd_thread, &thread_return); pthread_join(rcv_thread, &thread_return); close(sock); return 0; } //發送消息 void * send_msg(void * arg) { int sock = *((int *)arg); char name_msg[NAME_SIZE + BUF_SIZE]; while (1) { fgets(msg, BUF_SIZE, stdin); if (!strcmp(msg, "q\n") || !strcmp(msg, "Q \n")) { close(sock); exit(0); } sprintf(name_msg, "%s %s", name, msg); write(sock, name_msg, strlen(name_msg)); } return NULL; } //接收消息 void * recv_msg(void * arg) { int sock = *((int *)arg); char name_msg[NAME_SIZE + BUF_SIZE]; int str_len; while (1) { str_len = read(sock, name_msg, NAME_SIZE + BUF_SIZE - 1); if(str_len == -1) return (void *)-1; name_msg[str_len] = 0; fputs(name_msg, stdout); } return NULL; } void error_handling(char *message) { fputs(message, stderr); fputc('\n', stderr); exit(1); }

TCP/IP網絡編程 多線程服務器端的實現
TCP/IP網絡編程 多線程服務器端的實現
TCP/IP網絡編程 多線程服務器端的實現

  艾銻無限是中國領先IT外包服務商,專業為企業提供IT運維外包、電腦維護網絡維護、網絡布線、辦公設備維護、服務器維護數據備份恢復、門禁監控、網站建設等多項IT服務外包,服務熱線:400-650-7820 聯系電話:010-62684652 咨詢QQ1548853602 地址:北京市海淀區北京科技會展2號樓16D,用心服務每一天,為企業的發展提升更高的效率,創造更大的價值。

  更多的IT外包信息盡在艾銻無限http://www.whgoodly.com


相關文章

IT外包服務
二維碼 關閉
主站蜘蛛池模板: 欧美精产国品一二三类产品特点_久久久亚洲精品一区二区三区_夭天干天天躁天天摸_AV在线观看_免费毛片av_成人AV免费视频_91色伦_日本aaaa片毛片免费观看视频 | 国产清纯白嫩初高生在线播放视频_雨宫琴音av一区在线播放_午夜影院在线观看视频_黄色动漫视频在线观看_亚洲精品88p_极品少妇xxxx精品少妇_欧洲一区二区在线_久久久蜜桃精品 | 国产精品九九九九九_精品久久久久久久久久ntr影视_中文字幕一区av_狼人久久乐_无码乱码av天堂一区二区_免费观看成人毛片a片2008_日韩有码在线观看_伊人久久精品无码二区麻豆 | 国产精品超碰_国产精品久久久久久久成人午夜_综合久久2o19_上司部长出轨漂亮人妻_成人九色_互换后人妻的呻吟晓红_国产精品欧美_亚洲mv大片欧洲mv大片 | 日本一级a毛片免费观看_69av导航_久久夜色精品国产噜噜亚洲AV_精品成人A区在线观看_gogogo免费高清在线_免费午夜影片_综合激情久久综合激情_黄页在线观看免费 | 久久中文字幕无码一区二区_亚洲av成人一区二区三区观看_av影音先锋天堂网_免费看av毛片多人群伦_夜夜夜夜曰天天天天拍国产_欧美视频区_日本不卡免费播放_国内精品免费久久久久软件 色狠狠av五综合久久久_四虎影院最新网址_国产精品久久久久久久模特_一区二区在线不卡_18禁黄网站禁片免费观看女女_91成人影院_色老大影院www.97uuu.com_精品区一区二区三 | 久久激情av_欧美日韩精品一区二区三区高清视频_国产精品久久久久久久久果冻传媒_www.av黄_四虎影视久久久免费观看_亚洲精品影院在线_深夜福利备好纸巾18禁止_亚洲va | 亚洲AV成人午夜福利在线观看_成人国产在线视频_久久在现_黄色一级毛片儿_色中色登陆器_99久久无色码中文字幕人妻蜜柚_91日韩精品一区二区三区_久久精品欧美视频 | 日本天天躁狠狠躁噜噜噜_av无码免费岛国动作片片段_丁香五月激情综合激情综合激情_久草视频看看_小小拗女一区二区三区_亚洲免费av第一区第二区_久章草在线精品视频免费观看_老师好湿好紧我要进去了在线观看 | 美丽姑娘免费高清观看_欧美黑人狂躁日本寡妇_亚洲精品久久无码AV片亚洲有色_国产日韩欧美另类_西西大尺度美軳人人体bt_一个人看的免费视频WWW中文字幕_天堂网www天堂在线资源库_伊人黄网 | 国产香蕉一区二区三区_久久中文高清_中文字幕精品在线播放_在线免费看黄视频_国产午夜成人AV在线播放_成人福利在线观看视频_高清亚洲_免费超碰 | jizzyou日本_国产色精品VR一区二区_亚洲av图片_久久久WWW成人免费毛片_成人午夜精品无码区久久_狠狠操她_国产一级片中文字幕_JAPANESEHD无码中文字幕 | 国产成人无码精品久久久免费_国产xxxx_欧美成人免费_97超碰97_色欲蜜桃AV无码中文字幕_老司机精品在线_九色视屏_av片免费看 | 国产精品亚洲片在线播放_久久综合九色综合欧美就去吻_男人扒开女人腿喷水视频_天天久久久_www.黄色片_日韩AV一区三区_国产制服丝袜免费视频_亚洲第一综合最大av | 亚洲黄色小说图片_国产精品久久久久久久综合_色一乱一伦一图一区二区精品_免费gogo少妇大尺寸视频_欧美成免费A级毛片_伊人色吧_性猛交xxxx免费看蜜桃_亚洲第一伊人 | 狼群社区WWW在线中文_精品国偷自产在线视频_人妻被中出不敢呻吟A片视频_99久久精品国产网站_九九在线视频_国产h片在线观看_国产美女被遭强高潮免费_欧洲vodafone精品性 | 国产熟妇与子伦_亚洲婷婷在线视频_中文在线中文a_夜夜春亚洲嫩草一区二区_777米奇色8888狠狠俺去了_香蕉视频在线观看亚洲_亚洲国产日韩在线人成蜜芽_色大18成网站www在线观看 | 亚洲成人黄色在线观看_九一精品视频_天天弄天天模_av免费一区_亚洲一区精品视频在线观看_日韩精品久久无码人妻中文字幕_琪琪五月_久久中文字幕一区二区三区 | 操欧美丝袜_老熟女重囗味HDXX70星空_亚洲国产成人自拍_国产超碰网页_1024看片金沙日韩一区二区_免费观看AV在线网站网址_亚洲一区二区三区日韩_国产一级小视频 | 国产精品爱久久久久久久小说_黄色一级大片在线观看_久久精品99久久_91在线视频免费观看_www.51色.com_涩爱av色老久久精品偷偷鲁_成人二区_一本之道伊人 | 蜜臀AV无码一区二区三区_性色AV一区二区三区V视界影院_久久久久久一区_国产99视频精品免费播放照片_午夜精品一区二区三区福利视频_97精品人人A片免费看_无码专区AAAAAA免费视频_娇喘抽搐高潮喷水A片免费观看 | 中文字幕不卡免费视频_亚洲欧美日韩另类精品一区_少妇午夜三级伦理影院播放器_亚洲精品乱码久久观看网_久青草无码视频在线观看_在线不卡a资源高清_欧美第2页_亚洲国产成人在线播放 | 国产伦精品一区二区三区四区免费_自拍偷拍视频二区_不卡国产一区二区三区四区_69ww免费视频播放器_成人免费区_免费视频三区_欧美x亚洲_亚洲国产成人精品青青草原 | 熟妇人妻AV中文字幕老熟妇_成人18毛片_av基地网_国产区视频一区_天天爽夜夜爽人人爽QC_欧美一级淫片在线观看_中文字幕精品久久久_丰满五十路熟女正在播放 | 国产精品粉嫩av_婷婷国产一区综合久久精品_女同免费观看码_99精品免费久久久久久久久日本_欧美精品一区二区三区久久久竹菊_国产午夜精品一区理论片_在线视频麻豆_亲亲草在线视频 | 最新国产一区_精品91久久久久_国模吧久久_色婷婷在线精品国自产拍_日韩在线高清_一级黄色片aaa_日本理论中文字幕_亚洲无码一区二区三区 | 91成人亚洲综合欧美日韩_亚洲福利精品视频_正在播放白领少妇第一次_亚洲人成网站观看在线播放_久久精品h_亚洲乱码日产精品bd在线观看_中文视频一区视频二区视频三区_人禽杂交18禁网站免费 | 强乱中文字幕亚洲精品_亚洲网站观看_台湾无码AV一区二区三区_北条麻妃在线_国产在线一区二区三区视频_日韩精品无码视频免费专区_亚洲精品入口a级_亚洲日日摸夜夜夜夜夜爽小说 | 女同性恋一区_毛片a区_久久国产人妻无码一区_网红主播大秀福利视频日韩精品_欧美天天影院_国产亚洲日本精品无码_好大好硬好深好爽想要_国产麻豆剧传媒精品AV | 午夜在线观看影院_一区二区免费av_黄色录像久久_国产普通话尤物吞精视频_丰满少妇被猛烈进入毛片_毛片在线免费观看网站_我把护士日出水了视频_www.亚洲视频.com | 免费观看黄色毛片_男人靠女人免费视频网站_久久精品一二_在线免费h视频_国产在线高清精品_国产91xxx在线观看大全_东京一本到熟无码免费视频_91亚洲精品中文字幕 | 少妇高清一区二区免费看_精品久久久久久久久久久久久久久久久久_国产真实迷奷系列_99国产精品99久久久久久粉嫩_国产高潮流白浆免费视频_欧美黑人添添高潮a片www_国产精品视品_久久免费看少妇高潮a片特黄 | 91大片在线观看_天堂网WWW在线资源最新版_一本久道综合在线中文无码_午夜免费时刻_精品无吗乱吗av国产爱色_免费人成视频19674不收费_一本大道香一蕉久_男人久久久 | 91精品国产色综合久久不卡98最新章节_国产精品久草_亚洲不卡av一区二区三区_国产欧美日韩精品一区二区三区_妺妺窝人体色WWW网_九九九视频在线观看_亚洲国产婷婷综合在线精品_亚洲综合熟女久久久30p | 免费观看国产精品视频_欧洲美女粗暴牲交视频免费_香蕉影院在线_国产区精品福利在线社区_一区二区三区影视_亚州激情_69影院少妇在线观看_国产三级精品三级男人的天堂 | 国内精品影视无广告_激情国产一区二区_日韩一区二区免费在线观看_免费看的av网站_91久久色_国产综合不卡_www麻豆_日韩视频网站在线观看 | 国产尤物精品自在拍视频首页_91在线成人_久久黄视频_youjizz丰满熟妇中国_熟女俱乐部五十路二区AV_国产精品久久久久久亚洲色_久久999_zzijzzij亚洲日本少妇熟睡 九色在线网站_日韩一级黄_老人把我添到了高潮A片_免费看片的视频69xxx_欧美在线欧美在线_精品久久久国产_精品日韩av_精品无人区无码乱码大片国产 | 久久永久免费视频_凹凸69堂国产成人精品_亚洲第一极品精品无码久久_19禁无遮挡啪啪无码网站_亚洲精品乱码久久久久久久久久久久_99人人爽_欧美日韩一区二_亚洲国产日韩一区二区三区 免费动漫黄爽A片在线观看_一区精品视频_91在线无精精品秘?入口九色_av网站免费播放_亚洲综合无码精品一区二区三区_国产精品嫩草99a_av免费看国产_日韩αv在线 | h无码精品动漫尤物_亚洲亚洲人成网站网址_又黄又爽又无遮挡免费的网站_另类免费视频_国产强奷女交警在线播放_国产清纯91天堂在线观看_日本福利视频一区二区三区_健身教练啪啪偷拍一区二区 | 成人性做爰aaa片免费看_日本激情视频中文字幕_变形金刚之超能勇士免费观看_国产精品亚洲а∨无码播放不卡_91红桃视频_良家小少妇潮喷内射_久久99精品久久久久久园产越南_国产又色又爽又刺激视频 | 无码av片在线观看免费_国产成人综合视频在线_99精品国产高清一区二区麻豆_日日日插插插_日本黄网免费一区二区精品_少妇色欲网_国产精品成人麻烦视频_黄色大片入口 |