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://m.whgoodly.com


相關文章

IT外包服務
二維碼 關閉
主站蜘蛛池模板: av视屏_黄网站在线观_被两个黑人玩得站不起来了_黄色毛片大全_国产精品人妻无码久久久_成人性生交大片免费视频_黄色视网站_综合欧美亚洲 | 草久在线观看_黑料av_久久丫免费无码一区二区_免费的色网站_亚洲欧洲中文日韩乱码av_色拍拍噜噜噜3av在线_中国XXXX真实偷拍_www.夜夜操 | 国产福利视频网站_免费成年人视频在线观看_四lll少妇bbbb搡bbbb_精品久久久久久无码人妻_蜜臀成人_一区二区三区在线观看免费视频_亚洲欧美国内爽妇网_日本无遮挡吸乳呻吟视频 | 国产国语性生话播放_国一级片_成人拍拍视频_色婷婷综合久久久久中文图片_av在线亚洲男人的天堂_在线观看麻豆国产成人AV在线播放_女人一级片_一区一区视频 www视频在线观看免费_五月天狠狠干_精精国产视频_黄色一二三区_精品视频国产_操人网址_成年人视频在线免费看_狠狠操操 | 国产高清在线视频观看_欧美肉大捧一进一出免费视频_台湾91视频_亚洲国产精品无码久久久不卡_成人激情视频在线观看_国产成人免费视频网站高清观看视频_国内黄色大片_九九视频免费在线 | 91网在线看_国产放荡AV剧情演绎麻豆_日本一道本高清_亚洲国产AV一区二区三区四区_成版人性视频_亚洲曰本AV在线天堂_成人免费精品_羞羞答答成人影院www | 亚洲av国产国产久青草_波多野结衣中文字幕免费观看_国产三级黄色片_亚洲熟熟妇xxxx_久草在线免费福利资源_国产精品69精品一区二区三区_久久久成人毛片无码_天天爽夜夜操 | 亚洲在线免费观看视频_野花社区观看在线www官网_热久久国产_亚洲国产精品无码观看久久_两个人的WWW免费视频_超乳爆乳上司在线观看_亚洲天堂一区在线观看_久久天天躁狠狠躁夜夜96流白浆 | 国产成人AV一区二区三区无码_超碰99在线观看_www.欧美成_在线精品自拍_狠狠操狠狠摸_九七影院97影院理论片久久_亚洲情a成黄在线观看动_久久911 | vr成人片在线播放网站_免费高清一区二区三区_精品国产青草久久久久96_国产一级牲交高潮片16_欧美视频精品全部免费观看_japan白嫩丰满少妇videoshd_粉嫩av一区二区三区四区五区_亚洲日韩av无码一区二区三区人 | 日本欧美一区二区三区在线观看_中国一级毛片黄_国产小u女在线未发育_国产精品无码午夜福利_性xxxx欧美老妇506070_wwwxxx日本在线观看_26uuu成人_97国产精品最好的产品 | 在线免费视频一区_黄色成人影院在线观看_精品白浆一区二区三区h_无码人妻丰满熟妇区10P_欧美精品福利视频_少妇人妻大乳在线视频_色视在线_熟妇女领导呻吟疯狂 | 国产一级午夜_欧美成人免费观看视频_日韩欧美在线观看_人人人人人你人人人人人_亚洲成人精品网_欧美城天堂网地址_日韩精品99_91精品国产日韩一区二区三区 精品国产日韩专区欧美第一页_亚洲丰满少妇xxxxx高潮对白_国产xxxx搡xxxxx搡麻豆_另类视频一区二区三区_伦理片一区二区三区_国产中文区4幕区2023_精品福利视频一区二区三区_美国十次狠狠色综合AV | 国产精品免费视频xxxx_日本精品一区二区三区四区的功能_国产午夜视频免费_欧美不卡在线视频_日日嗨av一区二区三区四区_国产高清乱伦自拍_无码男男肉片在线观看_国产午夜毛片 | 不卡一区二区三区视频_亚洲综合热_美女自卫慰黄网站_国产一区二区精品久久岳_精品无码欧美一区二区三区不卡_亚洲精品综合精品自拍_手机看片日本_熟妇人妻无乱码中文字幕真矢织江 | 日韩精品中文字幕无码专区_欧美日韩综合精品_91成人看片_蜜臀av免费一区二区三区久久乐_粉色视频在线观看免费观看_亚洲av日韩av综合_日本艳妓BBW高潮一19_女人扒开屁股让男人桶 | 播五月开心婷婷欧美综合_亚洲av午夜成人片动漫番_日本久久综合网_夜色资源网站ye321_新版天堂资源中文www官网_国产精品嫩草影院免费_久久精品福利_男人的天堂av社区在线 | 久久91成人_好爽快点深一点好大_国产aⅴ精品_亚洲91av_狠狠躁夜夜躁人人爽超碰97香蕉_ww国产内射精品后入国产_www一起操_国产精品第二页 | 久久久久久色_国产成人亚洲第一_91香蕉亚洲精品_欧美日韩国产中文字幕_天堂资源在线官网_夜色福利院在线观看免费_国产成网站18禁止久久影院_色青青草原桃花久久综合 | 欧美国产日韩在线_日韩黄色a_www.草草草_日韩欧美一级视频_久久99热这里只频精品6_国产精品入口福利_中文字幕在线观看第三页_久久成人影院精品99 | 精品人妻无码一区二区三区牛牛_中文字幕无码乱码人妻系列蜜桃_中文字幕亚洲码在线观看_欧美大片首页欧美大片首页_亚洲国产精品午夜在线观看_成人免费xxx在线观看_全球AV集中精品导航福利_国产午夜福利久久网 | 亚洲精品国产综合久久_中文成人无字幕乱码精品区_老司机精品免费视频_日韩精品人妻系列无码专区_国产成人精品免费视频大_久久6国产_日本特黄特色大片免费视频_大陆国产乱人伦 | 免费看奶头视频的网站_成人免费福利片_亚洲欧美日本国产专区一区_久久午夜羞羞影院免费观看_黄在线看_久久综合九色综合久久久精品综合_日本高清不卡三区_欧美三日本三级少妇三99大粗 | 欧洲熟妇大荫蒂高潮a片视频_人人射人人爱_涩涩小视频_欧美日韩一区二区精品_嫩草院一区二区乱码蜜臀_cba视频_粉嫩AV一区二区夜夜嗨_日韩精品一区二区免费 | 成人网在线播放_亚洲熟妇国产熟妇肥婆_成人无码区免费视频_久久国产大片_好爽好大久久久级淫片毛片小说_忘忧草日本在线WWW日本_中国白嫩精品bbwbbw_亚洲熟妇av午夜无码不卡 | 日产中文字幕在线观看_男人肌肌捅女人肌肌视频_99精品在线_四虎国产精品成人_在线一级成人_国产一区二区怡红院_欧美另类久久久精品_欧美顶级METART裸体全部自慰 | 日韩精品一区二区三区蜜臀_欧美精品总汇_真实国产乱子伦对白视频不卡_久热中文在线_撕开奶罩疯狂揉吮奶头_成年人av在线免费观看_欧美成网_日本一级待黄大片 | 免费观看在线A毛片_亚洲中文字幕无码久久2017_老司机伊人网_一本色道久久综合狠狠躁的推荐_99久热在线精品国产观看_成人公开视频在线观看_欧美younv交_无限看片的视频高清在线 | 艳母1-6在线播放_日韩精品一区二区久久_青青久草在线_三个男人躁我一个爽公交车上_国产在线欧美日韩精品一区_性国产丰满麻豆videosex_91亚洲影院_狠狠色综合色区 | 国内自拍五区_被黑人的巨茎日出白浆_中文字幕第一区二区_国产亚洲美女精品久久久_亚洲porn_国产伦一区二区三区色一情_人人草人人人_久久无码字幕中文久久无码 | 久久永久免费视频_凹凸69堂国产成人精品_亚洲第一极品精品无码久久_19禁无遮挡啪啪无码网站_亚洲精品乱码久久久久久久久久久久_99人人爽_欧美日韩一区二_亚洲国产日韩一区二区三区 免费动漫黄爽A片在线观看_一区精品视频_91在线无精精品秘?入口九色_av网站免费播放_亚洲综合无码精品一区二区三区_国产精品嫩草99a_av免费看国产_日韩αv在线 | 久草视频播放_国产精品久久久久久久久久新婚_天天操好逼_GOGOGO免费视频观看高清国语_日本丰满熟妇videossex8k_日本无码人妻精品一区二区视频_国产精品成人免费一区久久羞羞_手机在线色 | 国产精品老熟女一区二区三区_69久久夜色精品国产69蝌蚪网_四虎永久在线精品免费一区二区_永久免费在线_精品国产一区二区三区国产区_天天天天天操_久久久久久AV无码免费网站_亚洲高清一区二 | 女人高潮娇喘抽搐喷水视频_a成人毛片_好硬好湿好爽再深一点动态图视频_九色在线播放_粉嫩小仙女扒开双腿自慰_香港三级韩国三级日本三级国产_JK制服白丝超短裙自慰_亚洲永久网址在线观看 | 欧美黄色成人_91视频专区_亚洲一区福利视频_依依激情网_亚洲精品久久无码AV片银杏_亚洲AV国产AV一区无码_无码伊人久久大杳蕉中文无码_性色av蜜臀av牛牛影院 | 91手机在线播放_xxxxhd中国_少妇激情AV一区二区三区_日本a人精品_高大丰满40岁东北少妇_熟女熟妇人妻在线视频_99在线在线视频免费视频观看_日韩国产成人在线 | 91插视频_国产激情免费_无码人妻精品一区二区三区久久久_欧美精品二区中文乱码字幕高清_成人无遮挡18禁免费视频_www.好色_一区福利在线_亚洲性大片 | 免费看三片在线播放_天天爽影院一区二区在线影院_午夜性做爰免费看_中文字幕亚洲高清_尤物久久av一区二区三区亚洲_国产精品乱子_h免费观看_一牛蜜桃色香阁aⅴ | 久久久久久伊人_天堂va_中文字幕av一区二区三区人_99久久亚洲精品蜜臀_麻豆产精国品免费入口_午夜免费大片_麻豆中文字幕在线观看_欧美阿v高清资源在线 | 啪啪网址大全_久久999精品久久久有什么优势_久热精品在线中文字幕播放_日韩精品dvd_99re热视频在线_伦理三区_亚洲一区二区三区在线看_国产精品麻豆视频 | 国产东北肥熟老胖女_久久免费的精品国产v∧_日本国产一区_曰韩欧美_亚洲色图网友自拍_精品国产乱码久久久久禁果_色哟哟在线观看免费高清大_久久亚洲精品成人av |