IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> 电子词典(tcp多进程模型) -> 正文阅读

[网络协议]电子词典(tcp多进程模型)

项目要求:

1. 登录注册功能,不能重复登录,重复注册

2. 单词查询功能

3. 历史记录功能,存储单词,意思,以及查询时间

4. 基于TCP,支持多客户端连接

5. 采用数据库保存用户信息与历史记录

6. 将dict.txt的数据导入到数据库中保存。

7. 按下ctrl+c退出客户端后,注销该客户端的登录信息

格式要求:

1. main函数只跑逻辑,不允许跑功能代码

2. 功能代码封装成函数

服务器

ser.c定义文件

#include<stdio.h>
#include<sys/types.h>
#include<arpa/inet.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<string.h>
#include<unistd.h>
#include<signal.h>
#include<sys/wait.h>
#include<stdlib.h>
#include<time.h>
#include<sqlite3.h>
#include"ser.h"

void handler(int sig)
{
        while(waitpid(-1,NULL,WNOHANG)>0);
}

int do_insert(sqlite3* ser,char word[],char meaning[])
{
        char buf[256] = "";
        bzero(buf,sizeof(buf));
        sprintf(buf,"insert into serdic (word,meaning) values (\"%s\",\"%s\");",word,meaning);
        char* errmsg = NULL;
        if(sqlite3_exec(ser,buf, NULL, NULL, &errmsg) != SQLITE_OK)
        {
                fprintf(stderr, "__%d__ sqlite3_exec:%s\n", __LINE__, errmsg);
                return -1;
        }
        return 0;
}

int dict_input(sqlite3* ser)
{
        FILE * fp = fopen("dict.txt","r");
        if(fp == NULL)
        {
                MSG_ERR("fopen");
        }
        char word[128] = "";
        char meaning[128] = "";
        char buf[256] = "";
        int flag = 0;
        int sum = 0;
        while(1)
        {
                bzero(word,sizeof(word));
                bzero(meaning,sizeof(meaning));
                bzero(buf,sizeof(buf));
                if(fgets(buf,sizeof(buf),fp) == NULL)
                {
                        break;
                }
                int num = 0;
                int m = 0;
                int n = 0;
                while(buf[num] != '\n')
                {
                        if(buf[num] == ' ' && buf[num+1] == ' ')
                        {

                                flag++;
                        }
                        if(flag < 1)
                        {
                                word[m] = buf[num];
                                m++;
                        }
                        else
                        {
                                meaning[n] = buf[num];
                                n++;
                        }
                        num++;
                }
                flag = 0;
                do_insert(ser,word,meaning);
        }
        return 0;
}

sqlite3* create_sq()
{
        sqlite3* ser = NULL;
        if(sqlite3_open("./ser.db",&ser) != SQLITE_OK)
        {
                printf("err_code:%d\n", sqlite3_errcode(ser));
                printf("errmsg:%s\n", sqlite3_errmsg(ser));
                fprintf(stderr, "__%d__ sqlite3_open failed\n", __LINE__);
                return NULL;
        }
        printf("------sqlite3_open-success-------\n");

        char* sq1 = "create table if not exists serdic\
                     (word char,meaning char);";
        char* errmsg1 = NULL;
        if(sqlite3_exec(ser, sq1, NULL, NULL, &errmsg1) != SQLITE_OK)
        {
                fprintf(stderr, "__%d__ sqlite3_exec:%s\n", __LINE__, errmsg1);
                return NULL;
        }
        printf("------create-serdic-success------\n");

        char* sq2 = "create table if not exists usrinf\
                     (name char,password char,status char);";
        char* errmsg2 = NULL;
        if(sqlite3_exec(ser, sq2, NULL, NULL, &errmsg2) != SQLITE_OK)
        {
                fprintf(stderr, "__%d__ sqlite3_exec:%s\n", __LINE__, errmsg2);
                return NULL;
        }
        printf("------create-usrinf-success------\n");
        char* sq3 = "create table if not exists usrrec\
                     (name char,word char,time char);";
        char* errmsg3 = NULL;
        if(sqlite3_exec(ser, sq3, NULL, NULL, &errmsg3) != SQLITE_OK)
        {
                fprintf(stderr, "__%d__ sqlite3_exec:%s\n", __LINE__, errmsg3);
                return NULL;
        }
        printf("------create-usrrec-success------\n");

        dict_input(ser);
        return ser;
}

int his_insert(sqlite3 *ser,char word[],char head[])
{
        time_t t=0;
        struct tm* info=NULL;
        char str[64]="";
        char buf[128]="";
        bzero(str,sizeof(str));
        bzero(buf,sizeof(buf));
        time(&t);
        info=localtime(&t);
        sprintf(str,"%4d-%02d-%02d %02d:%02d:%02d\n",info->tm_year+1900,\
        info->tm_mon+1,info->tm_mday,info->tm_hour,info->tm_min,\
        info->tm_sec);
        sprintf(buf,"insert into usrrec (name,word,time) values (\'%s\',\'%s\',\'%s\');",head,word,str);
        char* errmsg1 = NULL;
        if(sqlite3_exec(ser,buf, NULL, NULL, &errmsg1) != SQLITE_OK)
        {
                fprintf(stderr, "__%d__ sqlite3_exec:%s\n", __LINE__, errmsg1);
                return -1;
        }
        return 0;
}

int ser_net()
{
        int sfd=socket(AF_INET,SOCK_STREAM,0);
        if(sfd<0)
        {
                MSG_ERR("socket");
        }
        printf("/-----create socket success-----/\n");

        int reuse=1;
        if(setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse))<0)
        {
                MSG_ERR("setsockopt");
        }

        struct sockaddr_in sin;
        sin.sin_family = AF_INET;
        sin.sin_port = htons(PORT);
        sin.sin_addr.s_addr = inet_addr(IP);

        if(bind(sfd, (struct sockaddr*)&sin, sizeof(sin)) < 0)
        {
                MSG_ERR("bind");
        }
        printf("/----------bind success---------/\n");

        if(listen(sfd,10)<0)
        {
                MSG_ERR("lisetn");
        }
        printf("/---------listen success--------/\n");

        return sfd;
}
int inf_search(sqlite3* ser,char head[])
{
        char buf[128]="";
        bzero(buf,sizeof(buf));
        sprintf(buf,"select * from usrinf where name like \'%s\';",head);
        char* errmsg1 = NULL;
        char **dbresult;
        int nrow,ncolumn;
        if(sqlite3_get_table(ser,buf, &dbresult, &nrow, &ncolumn, &errmsg1) == SQLITE_OK)
        {
                if(nrow != 0)
                {
                        return 1;
                }
        }
        return 0;
}


int sta_search(sqlite3* ser,char head[],char tail[])
{
        char buf[128]="";
        bzero(buf,sizeof(buf));
        sprintf(buf,"select * from usrinf where name like \'%s\' and password like \'%s\' and status like \'%s\';",head,tail,"online");
        char* errmsg1=NULL;
        char **dbresult;
        int nrow,ncolumn;
        if(sqlite3_get_table(ser,buf, &dbresult, &nrow, &ncolumn, &errmsg1) == SQLITE_OK)
        {
                if(nrow != 0)
                {
                        return 1;
                }
        }
        return 0;
}
int jug_pwd(sqlite3* ser,char head[],char tail[])
{
        char buf[128]="";
        bzero(buf,sizeof(buf));
        sprintf(buf,"select * from usrinf where name like \'%s\' and password like \'%s\';",head,tail);
        char* errmsg1=NULL;
        char **dbresult;
        int nrow,ncolumn;
        if(sqlite3_get_table(ser,buf, &dbresult, &nrow, &ncolumn, &errmsg1) == SQLITE_OK)
        {
                if(nrow != 0)
                {
                        return 1;
                }
        }
        return 0;
}

int sta_change(sqlite3* ser,char head[],int newfd)
{
        char buf[128]="";
        bzero(buf,sizeof(buf));
        sprintf(buf,"update usrinf set status=\'%s\' where name=\'%s\';","offline",head);
        char* errmsg1=NULL;
        if(sqlite3_exec(ser,buf, NULL, NULL, &errmsg1) != SQLITE_OK)
        {
                fprintf(stderr, "__%d__ sqlite3_exec:%s\n", __LINE__, errmsg1);
                return -1;
        }
        char mes[32]="";
        strcpy(mes,"you have offline");
        if(send(newfd,mes,sizeof(mes),0)<0)
        {
                MSG_ERR("send");
        }
        return 0;
}
int inf_insert(sqlite3* ser,char head[],char tail[])
{
        char buf[128] = "";
        bzero(buf,sizeof(buf));
        sprintf(buf,"insert into usrinf (name,password,status) values (\'%s\',\'%s\',\'%s\');",head,tail,"online");
        char* errmsg1 = NULL;
        if(sqlite3_exec(ser,buf, NULL, NULL, &errmsg1) != SQLITE_OK)
        {
                fprintf(stderr, "__%d__ sqlite3_exec:%s\n", __LINE__, errmsg1);
                return -1;
        }
        return 0;
}
int meaning_search(sqlite3* ser,int newfd,char word[])
{
        char buf[128]="";
        char meaning[64]="";
        bzero(buf,sizeof(buf));
        bzero(meaning,sizeof(meaning));
        sprintf(buf,"select * from serdic where word like \'%s\';",word);
        char* errmsg1=NULL;
        char **dbresult;
        int nrow,ncolumn;
        if(sqlite3_get_table(ser,buf, &dbresult, &nrow, &ncolumn, &errmsg1) != SQLITE_OK)
        {
                fprintf(stderr,"_%d_sqlite_get_table:%s\n",__LINE__,errmsg1);
                return -1;
        }
        if(nrow != 0)
        {
                strcat(meaning,dbresult[3]);
                if(send(newfd,meaning,sizeof(meaning),0)<0)
                {
                        MSG_ERR("send");
                }
                return 1;
        }
        else
        {
                strcat(meaning,"The word was not queried");
                if(send(newfd,meaning,sizeof(meaning),0)<0)
                {
                        MSG_ERR("send");
                }
        }
        return 0;
}

int record_search(sqlite3 *ser,int newfd,char head[])
{
        char buf[512]="";
        bzero(buf,sizeof(buf));
        sprintf(buf,"select * from usrrec where name like \'%s\';",head);
        char* errmsg1=NULL;
        char **dbresult;
        int nrow,ncolumn;
        if(sqlite3_get_table(ser,buf, &dbresult, &nrow, &ncolumn, &errmsg1) != SQLITE_OK)
        {
                fprintf(stderr,"_%d_sqlite_get_table:%s\n",__LINE__,errmsg1);
                return -1;
        }
        int flag=0;
        int i=0;
        int j=0;
        bzero(buf,sizeof(buf));
        for(i=3;i<(nrow+1)*ncolumn;i++)
        {
                strcat(buf,dbresult[i]);
                j++;
                if(j==3)
                {
                        continue;
                        j=0;
                }
                strcat(buf," ");
        }
        if(send(newfd,buf,sizeof(buf),0)<0)
        {
                MSG_ERR("send");
        }
        return 0;
}
int rcv_cli_msg(sqlite3* ser,int newfd,struct sockaddr_in cin)
{
        char buf[128]="";
        char str[128]="";
        char head[64]="";
        char tail[64]="";
        ssize_t res=0;
        while(1)
        {
                bzero(buf,sizeof(buf));
                res=recv(newfd,buf,sizeof(buf),0);
                if(res<0)
                {
                        MSG_ERR("recv");
                }
                else if(0==res)
                {
                        printf("[%s : %d] newfd = %d client off-line\n",\
                        inet_ntoa(cin.sin_addr), ntohs(cin.sin_port),newfd);
                        return -1;
                }
                if(buf[0]=='@' || buf[0]=='#')
                {
                        int flag = 0;
                        int i=1;
                        int j=0;
                        while(buf[i] != 0)
                        {
                                if(buf[i] == '/')
                                {
                                        flag=1;
                                }
                                if(flag == 0)
                                {
                                        head[i-1]=buf[i];
                                }
                                else
                                {
                                        tail[j]=buf[i+1];
                                        j++;
                                }
                                i++;
                        }
                        if(inf_search(ser,head) == 1)
                        {
                                bzero(str,sizeof(str));
                                if(buf[0]=='@')
                                {
                                        strcpy(str,"@This account is registered");
                                }
                                else if(buf[0]=='#')
                                {
                                        if(sta_search(ser,head,tail)==1)
                                        {
                                                strcpy(str,"#This account is logged in");
                                        }
                                        else
                                        {
                                                if(jug_pwd(ser,head,tail)==1)
                                                {
                                                        strcpy(str,"!Logged in success");
                                                }
                                                else
                                                {
                                                        strcpy(str,"#Password is wrong");
                                                }
                                        }
                                }
                                if(send(newfd,str,sizeof(str),0) < 0)
                                {
                                        MSG_ERR("send");
                                }
                        }
                        else
                        {
                                bzero(str,sizeof(str));
                                if(buf[0]=='@')
                                {
                                        inf_insert(ser,head,tail);
                                        strcpy(str,"!Registered success");
                                }
                                else if(buf[0]=='#')
                                {
                                        strcpy(str,"#The account does not exist");
                                }
                                if(send(newfd,str,sizeof(str),0) < 0)
                                {
                                        MSG_ERR("send");
                                }
                        }
                }
                else
                {
                        if(buf[0]=='(')
                        {
                                char word[128]="";
                                strcpy(word,buf+1);
                                if(meaning_search(ser,newfd,word)==1)
                                {
                                        his_insert(ser,word,head);
                                }
                        }
                        else if(buf[0]==')')
                        {
                                char head[128]="";
                                strcpy(head,buf+1);
                                record_search(ser,newfd,head);
                        }
                        else
                        {
                                sta_change(ser,head,newfd);
                        }
                }
        }
}






ser.h声明文件

#ifndef __server_h__
#define __server_h__

#define MSG_ERR(msg) do{fprintf(stderr,"_%d_",__LINE__);perror(msg);return -1;}while(0)

#define PORT 8888
#define IP "192.168.31.240"

typedef void(*sighandler_t)(int);

void handler(int sig);

int do_insert(sqlite3* ser,char word[],char meaning[]);

int dict_input(sqlite3* ser);

sqlite3* create_sq();

int his_insert(sqlite3 *ser,char word[],char head[]);

int ser_net();

int inf_search(sqlite3* ser,char head[]);

int sta_search(sqlite3* ser,char head[],char tail[]);

int jug_pwd(sqlite3* ser,char head[],char tail[]);

int sta_change(sqlite3* ser,char head[],int newfd);

int inf_insert(sqlite3* ser,char head[],char tail[]);

int meaning_search(sqlite3* ser,int newfd,char word[]);

int record_search(sqlite3 *ser,int newfd,char head[]);

int rcv_cli_msg(sqlite3* ser,int newfd,struct sockaddr_in cin);

#endif

sermain.c主函数

#include<stdio.h>
#include<sys/types.h>
#include<arpa/inet.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<string.h>
#include<unistd.h>
#include<signal.h>
#include<sys/wait.h>
#include<stdlib.h>
#include<time.h>
#include<sqlite3.h>
#include"ser.h"

int main()
{
        sighandler_t s=signal(17,handler);
        if(SIG_ERR==s)
        {
                MSG_ERR("signal");
        }

        sqlite3* ser=create_sq();
        int sfd=ser_net();
        struct sockaddr_in cin;
        socklen_t addrlen=sizeof(cin);

        int newfd=0;
        pid_t pid=0;
        while(1)
        {
                newfd=accept(sfd,(struct sockaddr*)&cin,&addrlen);
                printf("[%s : %d] newfd = %d client on-line\n",\
                inet_ntoa(cin.sin_addr), ntohs(cin.sin_port),newfd);
                if(newfd<0)
                {
                        MSG_ERR("accept");
                }
                pid=fork();
                if(pid>0)
                {
                        close(newfd);
                }
                else if(0==pid)
                {
                        close(sfd);
                        rcv_cli_msg(ser,newfd,cin);
                        close(newfd);
                        exit(0);
                }
                else
                {
                        MSG_ERR("fork");
                }
        }
        close(sfd);
        return 0;
}


客户端

cli.c定义文件

#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<unistd.h>
#include<string.h>
#include<stdlib.h>
#include<signal.h>
#include"cli.h"

void handler(int sig)
{
        char mes[32]="";
        strcpy(mes,"quit");
        if(send(sfd,mes,sizeof(mes),0)<0)
        {
                perror("send");
                return;
        }
        bzero(mes,sizeof(mes));
        if(recv(sfd,mes,sizeof(mes),0)<0)
        {
                perror("recv");
                return;
        }
        printf("\n%s\n",mes);
        exit(0);
}

int cli_net()
{
        int sfd = socket(AF_INET, SOCK_STREAM, 0);
        if(sfd < 0)
        {
                MSG_ERR("socket");
        }

        struct sockaddr_in sin;
        sin.sin_family = AF_INET;
        sin.sin_port = htons(PORT);
        sin.sin_addr.s_addr = inet_addr(IP);

        if(connect(sfd, (struct sockaddr*)&sin, sizeof(sin)) < 0)
        {
                MSG_ERR("connect");
        }
        return sfd;
}

int usr_inf(int sfd)
{
        printf("/------1.Enroll------/\n");
        printf("/------2.Login-------/\n\n");
        int choice;
        char buf[128]="";
        char ID[63]="";
        char password[63]="";
        printf("Enter your choice >>> ");
        scanf("%d",&choice);
        while(getchar() != '\n');
        bzero(buf,sizeof(buf));
        bzero(ID,sizeof(ID));
        bzero(password,sizeof(password));
        printf("Enter your ID >>>  ");
        fgets(ID,sizeof(ID),stdin);
        ID[strlen(ID)-1] = 0;
        printf("Enter your password >>>  ");
        fgets(password,sizeof(password),stdin);
        password[strlen(password)-1] = 0;
        if(choice==1)
        {
                sprintf(buf,"%c%s%c%s",'@',ID,'/',password);
        }
        else
        {
                sprintf(buf,"%c%s%c%s",'#',ID,'/',password);
        }
        if(send(sfd,buf,sizeof(buf),0) < 0)
        {
                MSG_ERR("send");
        }
        bzero(buf,sizeof(buf));
        if(recv(sfd,buf,sizeof(buf),0)<0)
        {
                MSG_ERR("recv");
        }
        printf("\nPrompt>>>");
        if(buf[0]=='@')
        {
                printf("%s\n\n",buf+1);
                return -1;
        }
        else if(buf[0]=='#')
        {
                printf("%s\n\n",buf+1);
                return -1;
        }
        else if(buf[0]=='!')
        {
                printf("%s\n\n",buf+1);
                return 0;
        }
}

int word_inquire(int sfd)
{
        char word[63]="";
        char meaning[64]="";
        char str[128]="";
        printf("Enter the word>>>");
        bzero(word,sizeof(word));
        fgets(word,sizeof(word),stdin);
        word[strlen(word)-1]=0;
        sprintf(str,"%c%s",'(',word);
        if(send(sfd,str,sizeof(str),0)<0)
        {
                MSG_ERR("send");
        }
        bzero(meaning,sizeof(meaning));
        if(recv(sfd,meaning,sizeof(meaning),0)<0)
        {
                MSG_ERR("recv");
        }
        printf("meaning:%s\n",meaning);
        return 0;
}
int record_inquire(int sfd)
{
        char buf[512]="";
        char str[128]="";
        char ID[31]="";
        printf("\nEnter the ID>>>");
        fgets(ID,sizeof(ID),stdin);
        ID[strlen(ID)-1]=0;
        sprintf(str,"%c%s",')',ID);
        if(send(sfd,str,sizeof(str),0)<0)
        {
                MSG_ERR("send");
        }
        bzero(buf,sizeof(buf));
        if(recv(sfd,buf,sizeof(buf),0)<0)
        {
                MSG_ERR("recv");
        }
        printf("\nUser Record>>>\n");
        printf("%s\n",buf);
        return 0;
}

int usr_quit(int sfd)
{
        char mes[32]="";
        strcpy(mes,"quit");
        printf("%s\n",mes);
        if(send(sfd,mes,sizeof(mes),0)<0)
        {
                MSG_ERR("send");
        }
        bzero(mes,sizeof(mes));
        if(recv(sfd,mes,sizeof(mes),0)<0)
        {
                MSG_ERR("recv");
        }
        printf("%s\n",mes);
}

   

cli.h声明文件

#ifndef __client_h__
#define __client_h__

#define MSG_ERR(msg) do{fprintf(stderr,"_%d_",__LINE__);perror(msg);return -1;}while(0)

#define PORT 8888
#define IP "192.168.31.240"

typedef void(*sighandler_t)(int);

int sfd;

void handler(int sig);

int cli_net();

int usr_inf(int sfd);

int word_inquire(int sfd);

int record_inquire(int sfd);

int usr_quit(int sfd);

#endif
~                             

climain.c主函数

#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<unistd.h>
#include<string.h>
#include<stdlib.h>
#include<signal.h>
#include"cli.h"


int main()
{
        sighandler_t s=signal(2,handler);
        if(SIG_ERR==s)
        {
                MSG_ERR("signal");
        }
        sfd=cli_net();
        char buf[128]="";
        while(usr_inf(sfd)!=0);
        ssize_t res=0;
        int cho;
        while(1)
        {
                printf("/----1.Query word------/\n");
                printf("/----2.Query record----/\n");
                printf("/----3.Quit systeam----/\n");
                printf("\nselect>>>");
                scanf("%d",&cho);
                while(getchar()!='\n');
                if(cho==1)
                {
                        word_inquire(sfd);
                }
                else if(cho==2)
                {
                        record_inquire(sfd);
                }
                else
                {
                        usr_quit(sfd);
                        exit(0);
                }
                printf("\n");
        }
        close(sfd);
        return 0;
}

            

运行结果图

用户数据 数据库

名字,密码,状态,在线是online,退出是offline

用户记录 数据库

?名字,单词,时间

(同一用户查询多次)

?

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2022-09-13 11:52:32  更:2022-09-13 11:56:09 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 9:44:34-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码