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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

网络编程项目(聊天室项目)

發(fā)布時(shí)間:2023/12/19 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 网络编程项目(聊天室项目) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一、實(shí)現(xiàn)目標(biāo)

一個(gè)在Linux下可以使用的聊天軟件,要求至少實(shí)現(xiàn)如下功能:
1. 采用Client/Server架構(gòu)
2. Client A 登陸聊天服務(wù)器前,需要注冊(cè)自己的ID和密碼
3. 注冊(cè)成功后,Client A 就可以通過(guò)自己的ID和密碼登陸聊天服務(wù)器
4. 多個(gè)Client X 可以同時(shí)登陸聊天服務(wù)器之后,與其他用戶進(jìn)行通訊聊天
5. Client A 成功登陸后可以查看當(dāng)前聊天室內(nèi)其他子啊先用戶Client x
6. Client A 可以選擇發(fā)消息給某個(gè)特定的 Client x,即“悄悄話”功能
7. Client A 可以選擇發(fā)消息給全部的在線用戶,即“群發(fā)消息”功能
8. Client A 在退出時(shí)需要保存聊天記錄
9. Server 端維護(hù)一個(gè)所有登陸用戶的聊天會(huì)的記錄文件,以便查看

可以選擇實(shí)現(xiàn)的附加功能:
1. Server 可以內(nèi)建一個(gè)特殊權(quán)限的賬號(hào)admin,用于管理聊天室
2. Admin 可以將某個(gè)Client X“踢出聊天室”
3. Admin 可以將某個(gè)Client X“設(shè)為只能旁聽(tīng),不能發(fā)言”
4. Client 端發(fā)言增加表情符號(hào),可以設(shè)置某些自定義的特殊組和來(lái)表達(dá)感情,如輸入:),則會(huì)自動(dòng)發(fā)送“XXX向大家做了個(gè)笑臉”
5. Client 段增加某些常用話語(yǔ),可以對(duì)其中某些部分進(jìn)行“姓名替換”,例如,輸入/ClientA/welcome,則會(huì)自動(dòng)發(fā)送“ClientA大俠,歡迎你來(lái)到咱們的聊天室”
Client.c源文件

#include <sys/types.h> #include <sys/socket.h> #include <stdio.h> #include <unistd.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> #include <stdlib.h> #include <sqlite3.h> #include <sys/stat.h> #include <fcntl.h> #include <time.h>#define PORT 9999char myName[20]; // 保存用戶名 char msg1[1024]; // 保存聊天信息sqlite3 * database;int flag1 = 0; // 線程退出的判斷條件(不退出) int flag2 = 0; // 文件傳輸確認(rèn)信號(hào)(無(wú)接收) int flag3 = 0; // 存在文件接收請(qǐng)求的判斷(不存在) int flag4 = 0; // 本地存儲(chǔ)是否被禁言(未被禁言)// 協(xié)議 struct Msg {char msg[1024]; // 消息內(nèi)容int cmd; // 消息類型char filename[50]; // 保存文件名char toname[20]; // 接收者姓名char fromname[20]; // 發(fā)送者姓名int sig; // 用戶狀態(tài)(0:管理員、1:普通用戶、2:被禁言) };struct Msg msg; // 全局變量?jī)蓚€(gè)線程共享// 注冊(cè)/登錄界面 void interface1() {system("clear");printf ("\t*************************** 網(wǎng)絡(luò)聊天室 *****************************\n");printf ("\t* *\n");printf ("\t* *\n");printf ("\t* 1、 注冊(cè) *\n"); printf ("\t* 2、 登錄 *\n");printf ("\t* q、 退出 *\n");printf ("\t* *\n");printf ("\t* *\n");printf ("\t* BY szw *\n");printf ("\t********************************************************************\n\n");printf ("\t***** 請(qǐng)輸入命令: ");}// 普通用戶界面 void interface2() {system("clear");printf ("\t*************************** 網(wǎng)絡(luò)聊天室 *****************************\n");printf ("\t* *\n");printf ("\t* *\n");printf ("\t* 1、 查看當(dāng)前在線人數(shù) *\n"); printf ("\t* 2、 進(jìn)入群聊界面 *\n");printf ("\t* 3、 進(jìn)入私聊界面 *\n");printf ("\t* 4、 查看聊天記錄 *\n");printf ("\t* 5、 文件傳輸 *\n");printf ("\t* 6、 更改密碼 *\n"); printf ("\t* 7、 在線注銷 *\n"); printf ("\t* Q、 退出聊天室 返回登錄界面 *\n");printf ("\t* *\n");printf ("\t* *\n");printf ("\t* BY szw *\n");printf ("\t********************************************************************\n\n");printf ("\t***** 請(qǐng)輸入命令: "); }// 管理員界面 void interface3() {system("clear");printf ("\t*************************** 網(wǎng)絡(luò)聊天室 *****************************\n");printf ("\t* *\n");printf ("\t* *\n");printf ("\t* 1、 查看當(dāng)前在線人數(shù) *\n"); printf ("\t* 2、 進(jìn)入群聊界面 *\n");printf ("\t* 3、 進(jìn)入私聊界面 *\n");printf ("\t* 4、 查看聊天記錄 *\n");printf ("\t* 5、 文件傳輸 *\n");printf ("\t* 6、 更改密碼 *\n"); printf ("\t* 7、 在線注銷 *\n"); printf ("\t* 8、 管理員界面 *\n"); printf ("\t* Q、 退出聊天室 返回登錄界面 *\n");printf ("\t* *\n");printf ("\t* *\n");printf ("\t* BY szw *\n");printf ("\t********************************************************************\n\n");printf ("\t***** 請(qǐng)輸入命令: "); }// 用來(lái)保存收到的聊天信息 void keep_msg(char * msg1) {// 打開(kāi)數(shù)據(jù)庫(kù)int ret = sqlite3_open("Histroy.db", &database);if (ret != SQLITE_OK){printf ("\t打開(kāi)數(shù)據(jù)庫(kù)失敗\n");return;}// 往histroy表中添加信息char buf[100];char *errmsg = NULL;sprintf (buf, "insert into histroy values('%s','%s','%s')",msg.fromname,msg.toname,msg1);ret = sqlite3_exec(database, buf, NULL, NULL, &errmsg);if (ret != SQLITE_OK){printf ("\t數(shù)據(jù)庫(kù)操作失敗:%s\n", errmsg);return;} }// 接收文件 void receive() {printf ("\n\t正在接收文件.....\n");int fd2 = open(msg.filename, O_WRONLY|O_CREAT, 0777);if (fd2 == -1){perror ("open fd2");return;}write (fd2, msg.msg, 1023);close (fd2); }// 用來(lái)監(jiān)聽(tīng)收到的信息 void *readMsg(void *v) {int socketfd = (int)v;while(1){if (flag1 == 1) // 判斷線程的退出條件{flag1 = 0; // 重置線程退出條件pthread_exit(NULL);} read (socketfd, &msg, sizeof(msg));switch(msg.cmd){case 9001: // 群聊sprintf (msg1, "收到一條來(lái)自%s的群消息:\n\t%s", msg.fromname,msg.msg);printf ("\n\n\t%s\n", msg1);printf ("\n\t回車(chē)鍵返回 \n");keep_msg (msg1);break;case 9002: // 私聊printf ("\n\t%s 發(fā)來(lái)一條消息:\n\t%s\n", msg.fromname, msg.msg);sprintf (msg1,"%s 向 %s 發(fā)送一條信息:\n\t%s",msg.fromname, msg.toname, msg.msg);printf ("\n\t回車(chē)鍵返回 \n");keep_msg (msg1);break;case 9003: // 處理發(fā)送失敗sleep(3);printf ("\n\t用戶不在線或不存在,發(fā)送失敗\n");printf ("\n\t回車(chē)鍵返回 \n");break;case 9004: // 是否存在文件接收確認(rèn)信號(hào)printf ("\n\n\t收到一條信息,輸入任一字符進(jìn)行回復(fù):");fflush(stdout);flag3 = 1;break; case 9005: // 文件傳輸請(qǐng)求被拒絕printf ("\n\t您發(fā)送的文件傳輸請(qǐng)求已被拒絕\n");printf ("\n\t回車(chē)鍵返回 \n");break;case 9006: // 文件傳輸請(qǐng)求已通過(guò)printf ("\n\t您發(fā)送的文件傳輸請(qǐng)求已通過(guò),請(qǐng)打開(kāi)文件傳輸界面進(jìn)行文件傳輸\n");printf ("\n\t回車(chē)鍵返回 \n");break;case 9007: // 接收文件if (flag2 != 1)printf ("\n\t已成功攔截 %s 給您發(fā)送的文件\n", msg.fromname);elsereceive();break;case 9008: // 文件傳輸完成 printf ("\n\t%s 給您發(fā)送的文件已全部接收完畢,請(qǐng)及時(shí)查看\n", msg.fromname);printf ("\n\t回車(chē)鍵返回 \n");flag2 = 0; // 重置文件傳輸確認(rèn)信號(hào)break;case 9009: // 密碼修改成功printf ("\n\t密碼修改成功!\n");sleep(1);break;case 9010: // 密碼輸入有誤printf ("\n\t密碼輸入有誤,修改失敗\n");usleep(1500000);break; case 9011: // 收到禁言信號(hào)printf ("\n\t您已被管理員禁言,將無(wú)法發(fā)送群聊信息\n");printf ("\n\t回車(chē)鍵返回 \n");flag4 = 1;break;case 9012: // 收到結(jié)除禁言信號(hào)printf ("\n\t您已被管理員解除禁言\n");printf ("\n\t回車(chē)鍵返回 \n");flag4 = 0;break;case 9013: // 收到被踢出信號(hào)printf ("\n\t您已被管理員踢出,即將退出聊天室....\n");//sleep (2);flag1 = 1; break;}usleep(400000);} }// 查看當(dāng)前在線人數(shù) void display (int socketfd) {msg.cmd = 1;write (socketfd, &msg, sizeof(struct Msg)); //向服務(wù)器發(fā)送請(qǐng)求usleep(100000);printf ("\n\t當(dāng)前在線人數(shù)為:%d\n", msg.cmd);printf ("\n\t回車(chē)鍵返回 \n");getchar(); }// 退出聊天室,返回登錄界面 void quit_chatroom (int socketfd) {msg.cmd = 10;strcpy (msg.fromname, myName);write (socketfd, &msg, sizeof(struct Msg)); //向服務(wù)器發(fā)送退出信號(hào) }// 進(jìn)入群聊界面 void chat1(int socketfd) {if (flag4 == 1){printf ("\n\t您已被管理員禁言,無(wú)法發(fā)送群聊信息...\n");return;}msg.cmd = 2;strcpy (msg.fromname, myName);strcpy(msg.toname, "all");printf ("\n\t請(qǐng)輸入您要發(fā)送的內(nèi)容:\n\t");scanf ("%s",msg.msg);getchar();write (socketfd, &msg, sizeof(struct Msg)); //向服務(wù)器發(fā)送請(qǐng)求printf ("\n\t發(fā)送完成,等待處理結(jié)果.....\n"); // usleep (500000); }// 進(jìn)入私聊界面 void chat2(int socketfd) { msg.cmd = 3;strcpy (msg.fromname, myName);printf ("\n\t請(qǐng)輸入您要發(fā)送的對(duì)象:\n\t");scanf ("%s",msg.toname);getchar();printf ("\t請(qǐng)輸入您要發(fā)送的內(nèi)容:\n\t");scanf ("%s",msg.msg);getchar();write (socketfd, &msg, sizeof(struct Msg)); //向服務(wù)器發(fā)送請(qǐng)求printf ("\n\t發(fā)送完成,請(qǐng)稍候.....\n");usleep (500000); }// 打印群聊歷史記錄 void chat1_hst() {system("clear");printf ("\t*************************** 網(wǎng)絡(luò)聊天室 *****************************\n\n\n");printf ("\t群聊歷史記錄: \n");// 打開(kāi)數(shù)據(jù)庫(kù)int ret = sqlite3_open("Histroy.db", &database);if (ret != SQLITE_OK){printf ("\t打開(kāi)數(shù)據(jù)庫(kù)失敗\n");return;}// 獲取histroy表中的信息char *errmsg = NULL;char **resultp = NULL;int nrow, ncolumn;char *sql = "select * from histroy";ret = sqlite3_get_table(database, sql, &resultp, &nrow, &ncolumn, &errmsg);if (ret != SQLITE_OK){printf ("數(shù)據(jù)庫(kù)操作失敗:%s\n", errmsg);return;}int i;for (i = 1+ncolumn; i < (nrow+1)*ncolumn; i+=ncolumn){if(strcmp(resultp[i], "all") == 0){printf ("\n\t%s\n", resultp[i+1]);}}sqlite3_free_table(resultp);// 關(guān)閉數(shù)據(jù)庫(kù)sqlite3_close(database); }// 打印私聊歷史記錄 void chat2_hst() {system("clear");printf ("\t*************************** 網(wǎng)絡(luò)聊天室 *****************************\n\n\n");printf ("\t私聊歷史記錄:\n");// 打開(kāi)數(shù)據(jù)庫(kù)int ret = sqlite3_open("Histroy.db", &database);if (ret != SQLITE_OK){printf ("\t打開(kāi)數(shù)據(jù)庫(kù)失敗\n");return;}// 獲取histroy表中的信息char *errmsg = NULL;char **resultp = NULL;int nrow, ncolumn;char *sql = "select * from histroy";ret = sqlite3_get_table(database, sql, &resultp, &nrow, &ncolumn, &errmsg);if (ret != SQLITE_OK){printf ("數(shù)據(jù)庫(kù)操作失敗:%s\n", errmsg);return;}int i;for (i = 1+ncolumn; i < (nrow+1)*ncolumn; i+=ncolumn){if(strcmp(resultp[i], "all") != 0){printf ("\n\t%s\n", resultp[i+1]);}}sqlite3_free_table(resultp);// 關(guān)閉數(shù)據(jù)庫(kù)sqlite3_close(database); }// 查看聊天記錄 void dis_histroy(int socketfd) {printf ("\n\t a、查看群聊記錄\n\t b、查看個(gè)人聊天記錄\n\t");printf ("\n\t***** 請(qǐng)選擇: ");switch (getchar()){case 'a':chat1_hst();break;case 'b':chat2_hst();break;}printf ("\n\t回車(chē)鍵返回 ");getchar(); }// 確認(rèn)傳輸對(duì)象 void convey_confirm(int socketfd) {msg.cmd = 5;strcpy (msg.fromname, myName);printf ("\n\t請(qǐng)輸入文件的傳輸對(duì)象:\n\t");scanf ("%s",msg.toname);getchar();printf ("\n\t傳輸請(qǐng)求發(fā)送完成,請(qǐng)稍等.....\n");write (socketfd, &msg, sizeof(struct Msg)); //向服務(wù)器發(fā)送請(qǐng)求 }// 文件傳輸過(guò)程 void convey_chose(int socketfd) {msg.cmd = 9007;strcpy (msg.toname, msg.fromname);strcpy (msg.fromname, myName);printf ("\n\t當(dāng)前目錄下的文件有: \n\n\t");fflush(stdout);system ("ls");printf ("\n\t請(qǐng)輸入您要傳送的文件名: ");printf ("\n\t");scanf ("%s",msg.filename);getchar();// 打開(kāi)要讀的文件int fd1 = open(msg.filename, O_RDONLY);if (fd1 == -1){perror ("open fd1");return;}int ret = 0;flag1 = 1; // 關(guān)閉線程while (ret = read (fd1, msg.msg, 1023)){if (ret == -1){perror("read");break;}printf ("\n\t正在傳輸文件,請(qǐng)稍候......\n");write (socketfd, &msg, sizeof(struct Msg));sleep(1);}msg.cmd = 9008;write (socketfd, &msg, sizeof(struct Msg));printf ("\n\t文件傳輸完成\n");close (fd1);// 重新開(kāi)啟一個(gè)線程pthread_t id;pthread_create(&id, NULL, readMsg, (void*)socketfd);pthread_detach(id); // getchar(); }// 文件傳輸界面 void convey(int socketfd) {system("clear");printf ("\t*************************** 網(wǎng)絡(luò)聊天室 *****************************\n\n\n");printf ("\t 1、傳輸對(duì)象確認(rèn)\n");printf ("\t 2、選擇文件\n");printf ("\n\t***** 請(qǐng)選擇: ");char ch[2];fgets(ch, 2, stdin);while (getchar()!= '\n');switch (ch[0]){case '1': // 確認(rèn)傳輸對(duì)象convey_confirm(socketfd);break;case '2': // 文件選擇convey_chose(socketfd);break;}printf ("\n\t回車(chē)鍵返回 ");getchar(); }// 更改密碼 void change_pass(int socketfd) {char ch[2];msg.cmd = 6;printf ("\n\t您是否確定需要修改密碼?(y/n): ");fgets(ch, 2, stdin);while (getchar()!= '\n');if (ch[0] != 'y'){printf ("\n\t請(qǐng)稍候.....\n");usleep(700000);return;}printf ("\t請(qǐng)輸入舊密碼: ");scanf ("%s", msg.msg);getchar();printf ("\t請(qǐng)輸入新密碼: ");scanf ("%s", msg.filename);getchar();strcpy (msg.fromname, myName);write (socketfd, &msg, sizeof(struct Msg)); // 向服務(wù)器發(fā)送注冊(cè)信息printf ("\n\t正在校驗(yàn)數(shù)據(jù),請(qǐng)稍候......\n");sleep(1); }// 在線注銷 void delete_user(int socketfd) {msg.cmd = 8;printf ("\n\t正在處理注銷操作......\n");write (socketfd, &msg, sizeof(struct Msg)); //向服務(wù)器發(fā)送請(qǐng)求sleep(1);printf ("\t注銷完成!\n"); }// 普通用戶操作 void user_do (int socketfd) { char ch[2];while(1){interface2();if (flag3 == 1){printf ("\n\n\t%s 請(qǐng)求傳輸文件,是否接收?(y/n):", msg.fromname);fflush(stdout);fgets(ch, 2, stdin);while (getchar()!= '\n');if (ch[0] != 'y'){printf ("\n\t您已拒絕接受文件傳輸\n");printf ("\n\t回車(chē)鍵返回 \n");}else {printf ("\n\t您已接受文件傳輸請(qǐng)求\n");printf ("\n\t回車(chē)鍵返回 \n");flag2 = 1;}if (flag2 == 0){msg.cmd = 9005; // 不接受文件strcpy (msg.toname,msg.fromname); // 修改信號(hào)發(fā)送對(duì)象strcpy (msg.fromname, myName);write (socketfd, &msg, sizeof(struct Msg)); }else if (flag2 == 1){msg.cmd = 9006; // 接受文件strcpy (msg.toname,msg.fromname); // 修改信號(hào)發(fā)送對(duì)象strcpy (msg.fromname, myName);write (socketfd, &msg, sizeof(struct Msg)); }flag3 = 0; // 重置是否存在文件接收請(qǐng)求的判斷flag2 = 0;}fgets(ch, 2, stdin);while (getchar()!= '\n'); switch(ch[0]){case '1': // 查看當(dāng)前在線人數(shù)display(socketfd);break;case '2': // 進(jìn)入群聊界面 chat1(socketfd);printf ("\n\t回車(chē)鍵返回 \n");getchar();break;case '3': // 進(jìn)入私聊界面 chat2(socketfd);printf ("\n\t回車(chē)鍵返回 \n");getchar();break;case '4': // 查看聊天記錄dis_histroy(socketfd);getchar();break;case '5': // 文件傳輸convey(socketfd);break;case '6': // 更改密碼change_pass(socketfd);break;case '7': // 在線注銷printf ("\n\t是否確認(rèn)注銷?(y/n): ");fgets(ch, 2, stdin);while (getchar()!= '\n');if (ch[0] != 'y'){printf ("\n\t請(qǐng)稍候.....\n");usleep(700000);break;}delete_user(socketfd);case 'q': // 退出聊天室 返回登錄界面flag1 = 1;quit_chatroom(socketfd);printf ("\n\t正在退出,請(qǐng)稍候......\n");break;}if (flag1 == 1) // 判斷退出條件{break;}system("clear");} }// 將成員禁言 void silent (int socketfd) {msg.cmd = 9011;strcpy (msg.fromname, myName);printf ("\n\t請(qǐng)輸入您要禁言的用戶:\n\t");scanf ("%s",msg.toname);getchar();write (socketfd, &msg, sizeof(struct Msg)); //向服務(wù)器發(fā)送請(qǐng)求printf ("\n\t操作完成,請(qǐng)稍候.....\n");usleep (500000); }// 將成員解除禁言 void silent_del (int socketfd) {msg.cmd = 9012;strcpy (msg.fromname, myName);printf ("\n\t請(qǐng)輸入您要解除禁言的用戶:\n\t");scanf ("%s",msg.toname);getchar();write (socketfd, &msg, sizeof(struct Msg)); //向服務(wù)器發(fā)送請(qǐng)求printf ("\n\t操作完成,請(qǐng)稍候.....\n");usleep (500000); }// 將成員踢出聊天室 void kickout (int socketfd) {msg.cmd = 9013;strcpy (msg.fromname, myName);printf ("\n\t請(qǐng)輸入您要踢出的用戶:\n\t");scanf ("%s",msg.toname);getchar();write (socketfd, &msg, sizeof(struct Msg)); //向服務(wù)器發(fā)送請(qǐng)求printf ("\n\t操作完成,請(qǐng)稍候.....\n");usleep (500000); }// 管理員權(quán)限 void supuser (int socketfd) {system("clear");printf ("\t*************************** 網(wǎng)絡(luò)聊天室 *****************************\n\n\n");printf ("\t 1、將成員禁言\n");printf ("\t 2、將成員解除禁言\n");printf ("\t 3、將成員踢出聊天室\n");printf ("\n\t***** 請(qǐng)選擇: ");char ch[2];fgets(ch, 2, stdin);while (getchar()!= '\n');switch (ch[0]){case '1': // 將成員禁言silent(socketfd);break;case '2': // 將成員解除禁言silent_del(socketfd);break; case '3': // 將成員踢出聊天室kickout(socketfd);break;}printf ("\n\t回車(chē)鍵返回 ");getchar(); }// 管理員操作 void supuser_do (int socketfd) { char ch[2];while(1){interface3();if (flag3 == 1){printf ("\n\n\t%s 請(qǐng)求傳輸文件,是否接收?(y/n):", msg.fromname);fflush(stdout);fgets(ch, 2, stdin);while (getchar()!= '\n');if (ch[0] != 'y'){printf ("\n\t您已拒絕接受文件傳輸\n");printf ("\n\t回車(chē)鍵返回 \n");}else {printf ("\n\t您已接受文件傳輸請(qǐng)求\n");printf ("\n\t回車(chē)鍵返回 \n");flag2 = 1;}if (flag2 == 0){msg.cmd = 9005; // 不接受文件strcpy (msg.toname,msg.fromname); // 修改信號(hào)發(fā)送對(duì)象strcpy (msg.fromname, myName);write (socketfd, &msg, sizeof(struct Msg)); }else if (flag2 == 1){msg.cmd = 9006; // 接受文件strcpy (msg.toname,msg.fromname); // 修改信號(hào)發(fā)送對(duì)象strcpy (msg.fromname, myName);write (socketfd, &msg, sizeof(struct Msg)); }flag3 = 0; // 重置是否存在文件接收請(qǐng)求的判斷flag2 = 0;}fgets(ch, 2, stdin);while (getchar()!= '\n'); switch(ch[0]){case '1': // 查看當(dāng)前在線人數(shù)display(socketfd);break;case '2': // 進(jìn)入群聊界面 chat1(socketfd);printf ("\n\t回車(chē)鍵返回 \n");getchar();break;case '3': // 進(jìn)入私聊界面 chat2(socketfd);printf ("\n\t回車(chē)鍵返回 \n");getchar();break;case '4': // 查看聊天記錄dis_histroy(socketfd);getchar();break;case '5': // 文件傳輸convey(socketfd);break;case '6': // 更改密碼change_pass(socketfd);break;case '8': // 管理員權(quán)限操作supuser (socketfd);break;case '7': // 在線注銷printf ("\n\t是否確認(rèn)注銷?(y/n): ");fgets(ch, 2, stdin);while (getchar()!= '\n');if (ch[0] != 'y'){printf ("\n\t請(qǐng)稍候.....\n");usleep(700000);break;}delete_user(socketfd);case 'q': // 退出聊天室 返回登錄界面flag1 = 1;quit_chatroom(socketfd);printf ("\n\t正在退出,請(qǐng)稍候......\n");break;}if (flag1 == 1) // 判斷退出條件{break;}system("clear");} }// 登錄 void log_in(int socketfd) {char password[20];msg.cmd = 2;printf ("\n\t用戶登錄:\n");printf ("\t請(qǐng)輸入用戶名: ");scanf ("%s", myName);getchar();printf ("\t請(qǐng)輸入密碼: ");scanf ("%s", password);getchar();strcpy (msg.fromname, myName);strcpy (msg.msg, password);write (socketfd, &msg, sizeof(struct Msg)); // 向服務(wù)器發(fā)送登錄請(qǐng)求read (socketfd, &msg, sizeof(struct Msg)); // 讀取服務(wù)器的登錄回應(yīng)printf ("\n\t正在校驗(yàn)數(shù)據(jù)......\n");sleep(1);if (msg.cmd == 1002){printf ("\n\t驗(yàn)證通過(guò),正在登錄......\n");usleep(1500000);flag4 = msg.sig; // 更新禁言狀態(tài)// 線程分離,用來(lái)監(jiān)聽(tīng)服務(wù)器返回信息pthread_t id;pthread_create(&id, NULL, readMsg, (void*)socketfd);pthread_detach(id); user_do (socketfd);}else if (msg.cmd == 1003){printf ("\n\t驗(yàn)證通過(guò),正在登錄......\n");usleep(1500000);// 線程分離,用來(lái)監(jiān)聽(tīng)服務(wù)器返回信息pthread_t id;pthread_create(&id, NULL, readMsg, (void*)socketfd);pthread_detach(id); supuser_do (socketfd);} else if (msg.cmd == -4){printf ("\n\t此賬號(hào)已在別處登錄\n");}else if (msg.cmd == -3){printf ("\n\t驗(yàn)證失敗,請(qǐng)您確認(rèn)信息后重新登錄\n");}else if (msg.cmd == -2){printf ("\t驗(yàn)證失敗,數(shù)據(jù)庫(kù)打開(kāi)失敗\n");}else if (msg.cmd == -1){printf ("\t數(shù)據(jù)庫(kù)操作失敗\n");}usleep(1500000); }// 注冊(cè)(可注冊(cè)管理員) void reg(int socketfd) {msg.cmd = 1;printf ("\t用戶注冊(cè):\n");printf ("\t請(qǐng)輸入用戶名: ");scanf ("%s", myName);getchar();printf ("\t請(qǐng)輸入密碼: ");scanf ("%s", msg.msg);getchar();printf ("\t管理員: ");scanf ("%d", &msg.sig);getchar(); strcpy (msg.fromname, myName);write (socketfd, &msg, sizeof(struct Msg)); // 向服務(wù)器發(fā)送注冊(cè)信息read (socketfd, &msg, sizeof(struct Msg)); // 讀取服務(wù)器的注冊(cè)回應(yīng)printf ("\n\t正在校驗(yàn)數(shù)據(jù)......\n");sleep(1);if (msg.cmd == 1001){printf ("\n\t注冊(cè)成功!\n\t請(qǐng)稍候......\n");}else if (msg.cmd == -1){printf ("\t注冊(cè)失敗,該用戶名已被注冊(cè)\n");}else if (msg.cmd == -2){printf ("\t注冊(cè)失敗,數(shù)據(jù)庫(kù)打開(kāi)失敗\n");}usleep(1500000); }// 向服務(wù)器發(fā)送請(qǐng)求 void ask_server(int socketfd) {char ch[2];while (1){interface1();fgets(ch, 2, stdin);while (getchar()!= '\n');switch(ch[0]){case '1': // 注冊(cè)reg(socketfd);break;case '2': // 登錄log_in(socketfd);break;case 'q': // 退出exit(1);}system("clear");} }int main(int argc, char **argv) {// 打開(kāi)數(shù)據(jù)庫(kù)Histroy.dbint ret = sqlite3_open("Histroy.db", &database);if (ret != SQLITE_OK){printf ("打開(kāi)數(shù)據(jù)庫(kù)失敗\n");return -1;}// 創(chuàng)建 histroy 表char *errmsg = NULL;char *sql = "create table if not exists histroy(fromname TEXT,toname TEXT,msg TEXT)";ret = sqlite3_exec(database, sql, NULL, NULL, &errmsg);if (ret != SQLITE_OK){printf ("數(shù)據(jù)庫(kù)操作失敗:%s\n", errmsg);return -1;}// 關(guān)閉數(shù)據(jù)庫(kù)sqlite3_close(database);// 創(chuàng)建與服務(wù)器通信的套接字int socketfd = socket(AF_INET, SOCK_STREAM, 0);if (socketfd == -1){perror ("socket");return -1;}// 連接服務(wù)器struct sockaddr_in addr;memset(&addr, 0, sizeof(addr));addr.sin_family = AF_INET; // 設(shè)置地址族addr.sin_port = htons(PORT); // 設(shè)置本地端口inet_aton(argv[1],&(addr.sin_addr));// 連接服務(wù)器,如果成功,返回0,如果失敗,返回-1// 成功的情況下,可以通過(guò)socketfd與服務(wù)器進(jìn)行通信ret = connect(socketfd, (struct sockaddr *)&addr, sizeof(addr));if (ret == -1){perror ("connect");return -1;}printf ("成功連上服務(wù)器\n");ask_server(socketfd);// 關(guān)閉套接字close(socketfd);return 0; }

Server.c源文件

#include <sys/types.h> #include <sys/socket.h> #include <stdio.h> #include <unistd.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> #include <stdlib.h> #include <sqlite3.h> #define PORT 9999sqlite3 * database;// 協(xié)議 struct Msg {char msg[1024]; // 消息內(nèi)容int cmd; // 消息類型char filename[50]; // 保存文件名char toname[20]; // 接收者姓名char fromname[20]; // 發(fā)送者姓名int sig; // 用戶狀態(tài)(0:管理員、1:普通用戶、2:被禁言) };// 初始化套接字,返回監(jiān)聽(tīng)套接字 int init_socket() {//1、創(chuàng)建socketint listen_socket = socket(AF_INET, SOCK_STREAM, 0);if (listen_socket == -1){perror ("socket");return -1;}// 2、命名套接字,綁定本地的ip地址和端口struct sockaddr_in addr;memset(&addr, 0, sizeof(addr));addr.sin_family = AF_INET; // 設(shè)置地址族addr.sin_port = htons(PORT); // 設(shè)置本地端口addr.sin_addr.s_addr = htonl(INADDR_ANY); // 使用本地的任意IP地址int ret = bind(listen_socket, (struct sockaddr *)&addr, sizeof(addr));if (ret == -1){perror ("bind");return -1;}// 3、監(jiān)聽(tīng)本地套接字ret = listen(listen_socket, 5);if (ret == -1){perror ("listen");return -1;}printf ("服務(wù)器已就緒,等待客戶端連接.......\n");return listen_socket; }// 處理客戶端連接,返回與連接上的客戶端通信的套接字 int MyAccept(int listen_socket) {// 4、接收連接struct sockaddr_in client_addr; // 用來(lái)保存客戶端的ip和端口信息int len = sizeof(client_addr);int client_socket = accept(listen_socket, (struct sockaddr *)&client_addr, &len);if (client_socket == -1){perror ("accept");}printf ("成功接收一個(gè)客戶端: %s\n", inet_ntoa(client_addr.sin_addr));return client_socket; }// 查看當(dāng)前在線人數(shù) void display (int client_socket, struct Msg *msg) {printf ("查看當(dāng)前在線人數(shù)\n");// 確認(rèn)flag參數(shù)// 打開(kāi)數(shù)據(jù)庫(kù)int ret = sqlite3_open("User.db", &database);if (ret != SQLITE_OK){printf ("打開(kāi)數(shù)據(jù)庫(kù)失敗\n");msg->cmd = -2;write (client_socket, msg, sizeof(struct Msg));return;}// 與User表中信息進(jìn)行比對(duì)char *errmsg = NULL;char **resultp = NULL;int nrow, ncolumn;char *sql = "select * from User";ret = sqlite3_get_table(database, sql, &resultp, &nrow, &ncolumn, &errmsg);if (ret != SQLITE_OK){printf ("數(shù)據(jù)庫(kù)操作失敗:%s\n", errmsg);msg->cmd = -1;write (client_socket, msg, sizeof(struct Msg));return;}int count = 0;int i;for (i = 3+ncolumn; i < (nrow+1)*ncolumn; i+=ncolumn){if(strcmp(resultp[i], "1") == 0){count++;}}// 返回在線人數(shù)msg->cmd = count;printf ("當(dāng)前在線人數(shù)為:%d\n", msg->cmd);write (client_socket, msg, sizeof(struct Msg));sqlite3_free_table(resultp);// 關(guān)閉數(shù)據(jù)庫(kù)sqlite3_close(database);printf ("操作完成,已關(guān)閉數(shù)據(jù)庫(kù)\n"); }// 退出聊天室,返回登錄界面 void quit_chatroom (int client_socket, struct Msg *msg) {printf ("%s 退出聊天室\n", msg->fromname);// 打開(kāi)數(shù)據(jù)庫(kù)int ret = sqlite3_open("User.db", &database);if (ret != SQLITE_OK){printf ("打開(kāi)數(shù)據(jù)庫(kù)失敗\n");return;}char buf[100];char *errmsg = NULL;errmsg = NULL;sprintf (buf, "update user set flag = 0 where name = '%s'",msg->fromname);ret = sqlite3_exec(database, buf, NULL, NULL, &errmsg);if (ret != SQLITE_OK){printf ("數(shù)據(jù)庫(kù)操作失敗:%s\n", errmsg);return;}sqlite3_close(database);printf ("登錄狀態(tài)修改完畢,已關(guān)閉數(shù)據(jù)庫(kù)\n");write (client_socket, msg, sizeof(struct Msg)); }// 客戶端發(fā)送群聊消息 void chat1 (int client_socket, struct Msg *msg) {printf ("%s 發(fā)了一條群消息\n",msg->fromname);// 打開(kāi)數(shù)據(jù)庫(kù)int ret = sqlite3_open("User.db", &database);if (ret != SQLITE_OK){printf ("打開(kāi)數(shù)據(jù)庫(kù)失敗\n");msg->cmd = -2;write (client_socket, msg, sizeof(struct Msg));return;}// 獲取數(shù)據(jù)庫(kù)中的flag參數(shù)信息char *errmsg = NULL;char **resultp = NULL;int nrow, ncolumn;char *sql = "select * from User";ret = sqlite3_get_table(database, sql, &resultp, &nrow, &ncolumn, &errmsg);if (ret != SQLITE_OK){printf ("數(shù)據(jù)庫(kù)操作失敗:%s\n", errmsg);msg->cmd = -1;write (client_socket, msg, sizeof(struct Msg));return;}int i;for (i = 3+ncolumn; i < (nrow+1)*ncolumn; i+=ncolumn){// 查詢所有在線的用戶if(strcmp(resultp[i], "1") == 0){msg->cmd = 9001; write (atoi(resultp[i-1]), msg, sizeof(struct Msg)); }}printf ("群消息已全部發(fā)送完成\n"); }// 客戶端發(fā)送私聊消息 void chat2 (int client_socket, struct Msg *msg) {printf ("%s 向 %s 發(fā)了一條消息\n",msg->fromname,msg->toname);// 打開(kāi)數(shù)據(jù)庫(kù)int ret = sqlite3_open("User.db", &database);if (ret != SQLITE_OK){printf ("打開(kāi)數(shù)據(jù)庫(kù)失敗\n");msg->cmd = -2;write (client_socket, msg, sizeof(struct Msg));return;}// 獲取數(shù)據(jù)庫(kù)中的flag參數(shù)信息,判斷是否在線char *errmsg = NULL;char **resultp = NULL;int nrow, ncolumn;char *sql = "select * from User";ret = sqlite3_get_table(database, sql, &resultp, &nrow, &ncolumn, &errmsg);if (ret != SQLITE_OK){printf ("數(shù)據(jù)庫(kù)操作失敗:%s\n", errmsg);msg->cmd = -1;write (client_socket, msg, sizeof(struct Msg));return;}int i;for (i = 0+ncolumn; i < (nrow+1)*ncolumn; i+=ncolumn){if(strcmp(resultp[i], msg->toname)==0 && strcmp(resultp[i+3], "1")== 0){msg->cmd = 9002;write (atoi(resultp[i+2]), msg, sizeof(struct Msg));return;}}msg->cmd = 9003;write (client_socket, msg, sizeof(struct Msg)); }// 處理確認(rèn)文件傳輸對(duì)象 void convey_confirm (int client_socket, struct Msg *msg) {printf ("%s 向 %s 發(fā)送文件傳輸請(qǐng)求\n",msg->fromname,msg->toname);// 打開(kāi)數(shù)據(jù)庫(kù)int ret = sqlite3_open("User.db", &database);if (ret != SQLITE_OK){printf ("打開(kāi)數(shù)據(jù)庫(kù)失敗\n");return;}// 獲取數(shù)據(jù)庫(kù)中的flag參數(shù)信息char *errmsg = NULL;char **resultp = NULL;int nrow, ncolumn;char *sql = "select * from User";ret = sqlite3_get_table(database, sql, &resultp, &nrow, &ncolumn, &errmsg);if (ret != SQLITE_OK){printf ("數(shù)據(jù)庫(kù)操作失敗:%s\n", errmsg);return;}int i;for (i = 0+ncolumn; i < (nrow+1)*ncolumn; i+=ncolumn){if(strcmp(resultp[i], msg->toname)==0 && strcmp(resultp[i+3], "1")== 0){msg->cmd = 9004;write (atoi(resultp[i+2]), msg, sizeof(struct Msg));return;}}msg->cmd = 9003;write (client_socket, msg, sizeof(struct Msg)); }// 用戶不接受文件 void refuse (int client_socket, struct Msg *msg) {printf ("%s 拒絕了 %s 的文件傳輸請(qǐng)求\n",msg->fromname,msg->toname);// 打開(kāi)數(shù)據(jù)庫(kù)int ret = sqlite3_open("User.db", &database);if (ret != SQLITE_OK){printf ("打開(kāi)數(shù)據(jù)庫(kù)失敗\n");return;}// 獲取數(shù)據(jù)庫(kù)中 toname 的套接字char *errmsg = NULL;char **resultp = NULL;int nrow, ncolumn;char *sql = "select * from User";ret = sqlite3_get_table(database, sql, &resultp, &nrow, &ncolumn, &errmsg);if (ret != SQLITE_OK){printf ("數(shù)據(jù)庫(kù)操作失敗:%s\n", errmsg);return;}int i;for (i = 0+ncolumn; i < (nrow+1)*ncolumn; i+=ncolumn){if(strcmp(resultp[i], msg->toname)==0 && strcmp(resultp[i+3], "1")== 0){write (atoi(resultp[i+2]), msg, sizeof(struct Msg));return;}}msg->cmd = 9003;write (client_socket, msg, sizeof(struct Msg)); }// 用戶接受文件 void accept_ (int client_socket, struct Msg *msg) {printf ("%s 通過(guò)了 %s 的文件傳輸請(qǐng)求\n",msg->fromname,msg->toname);// 打開(kāi)數(shù)據(jù)庫(kù)int ret = sqlite3_open("User.db", &database);if (ret != SQLITE_OK){printf ("打開(kāi)數(shù)據(jù)庫(kù)失敗\n");return;}// 獲取數(shù)據(jù)庫(kù)中 toname 的套接字char *errmsg = NULL;char **resultp = NULL;int nrow, ncolumn;char *sql = "select * from User";ret = sqlite3_get_table(database, sql, &resultp, &nrow, &ncolumn, &errmsg);if (ret != SQLITE_OK){printf ("數(shù)據(jù)庫(kù)操作失敗:%s\n", errmsg);return;}int i;for (i = 0+ncolumn; i < (nrow+1)*ncolumn; i+=ncolumn){if(strcmp(resultp[i], msg->toname)==0 && strcmp(resultp[i+3], "1")== 0){write (atoi(resultp[i+2]), msg, sizeof(struct Msg));return;}}msg->cmd = 9003;write (client_socket, msg, sizeof(struct Msg)); }// 處理文件傳輸 void convey_chose (int client_socket, struct Msg *msg) {printf ("%s正在向%s傳輸文件......\n",msg->fromname,msg->toname);// 打開(kāi)數(shù)據(jù)庫(kù)int ret = sqlite3_open("User.db", &database);if (ret != SQLITE_OK){printf ("打開(kāi)數(shù)據(jù)庫(kù)失敗\n");msg->cmd = -2;write (client_socket, msg, sizeof(struct Msg));return;}// 獲取數(shù)據(jù)庫(kù)中的 flag 參數(shù)信息,判斷是否在線char *errmsg = NULL;char **resultp = NULL;int nrow, ncolumn;char *sql = "select * from User";ret = sqlite3_get_table(database, sql, &resultp, &nrow, &ncolumn, &errmsg);if (ret != SQLITE_OK){printf ("數(shù)據(jù)庫(kù)操作失敗:%s\n", errmsg);msg->cmd = -1;write (client_socket, msg, sizeof(struct Msg));return;}// 獲取toname的套接字int i;for (i = 0+ncolumn; i < (nrow+1)*ncolumn; i+=ncolumn){if(strcmp(resultp[i], msg->toname)==0 && strcmp(resultp[i+3], "1")== 0){write (atoi(resultp[i+2]), msg, sizeof(struct Msg));return;}}msg->cmd = 9003;write (client_socket, msg, sizeof(struct Msg)); }// 文件傳輸完成 void convey_complete (int client_socket, struct Msg *msg) {printf ("文件傳輸結(jié)束\n");// 打開(kāi)數(shù)據(jù)庫(kù)int ret = sqlite3_open("User.db", &database);if (ret != SQLITE_OK){printf ("打開(kāi)數(shù)據(jù)庫(kù)失敗\n");msg->cmd = -2;write (client_socket, msg, sizeof(struct Msg));return;}// 獲取數(shù)據(jù)庫(kù)中的 flag 參數(shù)信息,判斷是否在線char *errmsg = NULL;char **resultp = NULL;int nrow, ncolumn;char *sql = "select * from User";ret = sqlite3_get_table(database, sql, &resultp, &nrow, &ncolumn, &errmsg);if (ret != SQLITE_OK){printf ("數(shù)據(jù)庫(kù)操作失敗:%s\n", errmsg);msg->cmd = -1;write (client_socket, msg, sizeof(struct Msg));return;}// 獲取toname的套接字int i;for (i = 0+ncolumn; i < (nrow+1)*ncolumn; i+=ncolumn){if(strcmp(resultp[i], msg->toname)==0 && strcmp(resultp[i+3], "1")== 0){write (atoi(resultp[i+2]), msg, sizeof(struct Msg));return;}}msg->cmd = 9003;write (client_socket, msg, sizeof(struct Msg)); }// 更改密碼 void change_pass (int client_socket, struct Msg *msg) {printf ("%s請(qǐng)求修改密碼\n", msg->fromname);// 打開(kāi)數(shù)據(jù)庫(kù)int ret = sqlite3_open("User.db", &database);if (ret != SQLITE_OK){printf ("打開(kāi)數(shù)據(jù)庫(kù)失敗\n");msg->cmd = -2;write (client_socket, msg, sizeof(struct Msg));return;}// 與User表中信息進(jìn)行比對(duì)char *errmsg = NULL;char **resultp = NULL;int nrow, ncolumn;char *sql = "select * from user";ret = sqlite3_get_table(database, sql, &resultp, &nrow, &ncolumn, &errmsg);if (ret != SQLITE_OK){printf ("數(shù)據(jù)庫(kù)操作失敗:%s\n", errmsg);return;}int i;for (i = 0+ncolumn; i < (nrow+1)*ncolumn; i+=ncolumn){if(strcmp(resultp[i], msg->fromname)==0 && strcmp(resultp[i+1], msg->msg)==0){// 返回確認(rèn)信息msg->cmd = 9009;printf ("%s 驗(yàn)證通過(guò)\n", msg->fromname);write (client_socket, msg, sizeof(struct Msg));// 修改密碼char buf[100];errmsg = NULL;sprintf (buf, "update user set password = '%s' where name = '%s'",msg->filename,msg->fromname);ret = sqlite3_exec(database, buf, NULL, NULL, &errmsg);if (ret != SQLITE_OK){printf ("數(shù)據(jù)庫(kù)操作失敗:%s\n", errmsg);return;}sqlite3_free_table(resultp);// 關(guān)閉數(shù)據(jù)庫(kù)sqlite3_close(database);printf ("密碼修改完成,已關(guān)閉數(shù)據(jù)庫(kù)\n");return;}} printf ("%s 驗(yàn)證不通過(guò),密碼輸入有誤\n", msg->fromname);msg->cmd = 9010;write (client_socket, msg, sizeof(struct Msg));sqlite3_free_table(resultp);// 關(guān)閉數(shù)據(jù)庫(kù)sqlite3_close(database);printf ("操作完成,已關(guān)閉數(shù)據(jù)庫(kù)\n"); }// 客戶端請(qǐng)求在線注銷 void delete_user (int client_socket, struct Msg *msg) {printf ("即將處理用戶注銷\n");// 打開(kāi)數(shù)據(jù)庫(kù)int ret = sqlite3_open("User.db", &database);if (ret != SQLITE_OK){printf ("打開(kāi)數(shù)據(jù)庫(kù)失敗\n");return;}// 刪除 user 表中的信息char buf[100];char *errmsg = NULL;sprintf (buf, "delete from user where name = '%s'", msg->fromname);ret = sqlite3_exec(database, buf, NULL, NULL, &errmsg);if (ret != SQLITE_OK){printf ("數(shù)據(jù)庫(kù)操作失敗:%s\n", errmsg);return;}// 關(guān)閉數(shù)據(jù)庫(kù)sqlite3_close(database);printf ("刪除成功,已關(guān)閉數(shù)據(jù)庫(kù)\n"); }// 處理禁言請(qǐng)求 void silent (int client_socket, struct Msg *msg) {printf ("正在處理管理員 %s 對(duì)成員 %s 的禁言請(qǐng)求\n",msg->fromname,msg->toname);// 打開(kāi)數(shù)據(jù)庫(kù)int ret = sqlite3_open("User.db", &database);if (ret != SQLITE_OK){printf ("打開(kāi)數(shù)據(jù)庫(kù)失敗\n");msg->cmd = -2;write (client_socket, msg, sizeof(struct Msg));return;}// 獲取數(shù)據(jù)庫(kù)中的 flag 參數(shù)信息,判斷是否在線char *errmsg = NULL;char **resultp = NULL;int nrow, ncolumn;char *sql = "select * from User";ret = sqlite3_get_table(database, sql, &resultp, &nrow, &ncolumn, &errmsg);if (ret != SQLITE_OK){printf ("數(shù)據(jù)庫(kù)操作失敗:%s\n", errmsg);msg->cmd = -1;write (client_socket, msg, sizeof(struct Msg));return;}// 獲取toname的套接字int i;for (i = 0+ncolumn; i < (nrow+1)*ncolumn; i+=ncolumn){if(strcmp(resultp[i], msg->toname)==0 && strcmp(resultp[i+3], "1")== 0){msg->cmd = 9011;write (atoi(resultp[i+2]), msg, sizeof(struct Msg));char buf[100];errmsg = NULL;sprintf (buf, "update user set sig = 2 where name = '%s'",msg->toname);ret = sqlite3_exec(database, buf, NULL, NULL, &errmsg);if (ret != SQLITE_OK){printf ("數(shù)據(jù)庫(kù)操作失敗:%s\n", errmsg);return;}sqlite3_close(database);printf ("禁言狀態(tài)修改完畢,已關(guān)閉數(shù)據(jù)庫(kù)\n");return;}}msg->cmd = 9003;write (client_socket, msg, sizeof(struct Msg));sqlite3_close(database);printf ("用戶不在線,修改失敗,已關(guān)閉數(shù)據(jù)庫(kù)\n"); }// 處理解除禁言請(qǐng)求 void silent_del (int client_socket, struct Msg *msg) {printf ("正在處理管理員 %s 對(duì)成員 %s 的解除禁言請(qǐng)求\n",msg->fromname,msg->toname);// 打開(kāi)數(shù)據(jù)庫(kù)int ret = sqlite3_open("User.db", &database);if (ret != SQLITE_OK){printf ("打開(kāi)數(shù)據(jù)庫(kù)失敗\n");msg->cmd = -2;write (client_socket, msg, sizeof(struct Msg));return;}// 獲取數(shù)據(jù)庫(kù)中的 flag 參數(shù)信息,判斷是否在線char *errmsg = NULL;char **resultp = NULL;int nrow, ncolumn;char *sql = "select * from User";ret = sqlite3_get_table(database, sql, &resultp, &nrow, &ncolumn, &errmsg);if (ret != SQLITE_OK){printf ("數(shù)據(jù)庫(kù)操作失敗:%s\n", errmsg);msg->cmd = -1;write (client_socket, msg, sizeof(struct Msg));return;}// 獲取toname的套接字int i;for (i = 0+ncolumn; i < (nrow+1)*ncolumn; i+=ncolumn){if(strcmp(resultp[i], msg->toname)==0 && strcmp(resultp[i+3], "1")== 0){msg->cmd = 9012;write (atoi(resultp[i+2]), msg, sizeof(struct Msg));char buf[100];errmsg = NULL;sprintf (buf, "update user set sig = 1 where name = '%s'",msg->toname);ret = sqlite3_exec(database, buf, NULL, NULL, &errmsg);if (ret != SQLITE_OK){printf ("數(shù)據(jù)庫(kù)操作失敗:%s\n", errmsg);return;}sqlite3_close(database);printf ("禁言狀態(tài)修改完畢,已關(guān)閉數(shù)據(jù)庫(kù)\n");return;}}msg->cmd = 9003;write (client_socket, msg, sizeof(struct Msg));sqlite3_close(database);printf ("用戶不在線,修改失敗,已關(guān)閉數(shù)據(jù)庫(kù)\n"); }// 處理踢出成員 void kickout (int client_socket, struct Msg *msg) {printf ("正在處理管理員 %s 對(duì)成員 %s 的踢出請(qǐng)求\n",msg->fromname,msg->toname);// 打開(kāi)數(shù)據(jù)庫(kù)int ret = sqlite3_open("User.db", &database);if (ret != SQLITE_OK){printf ("打開(kāi)數(shù)據(jù)庫(kù)失敗\n");msg->cmd = -2;write (client_socket, msg, sizeof(struct Msg));return;}// 獲取數(shù)據(jù)庫(kù)中的 flag 參數(shù)信息,判斷是否在線char *errmsg = NULL;char **resultp = NULL;int nrow, ncolumn;char *sql = "select * from User";ret = sqlite3_get_table(database, sql, &resultp, &nrow, &ncolumn, &errmsg);if (ret != SQLITE_OK){printf ("數(shù)據(jù)庫(kù)操作失敗:%s\n", errmsg);return;}// 獲取toname的套接字int i;for (i = 0+ncolumn; i < (nrow+1)*ncolumn; i+=ncolumn){if(strcmp(resultp[i], msg->toname)==0 && strcmp(resultp[i+3], "1")== 0){msg->cmd = 9013;write (atoi(resultp[i+2]), msg, sizeof(struct Msg));char buf[100];errmsg = NULL;sprintf (buf, "update user set flag = 0 where name = '%s'",msg->toname);ret = sqlite3_exec(database, buf, NULL, NULL, &errmsg);if (ret != SQLITE_OK){printf ("數(shù)據(jù)庫(kù)操作失敗:%s\n", errmsg);return;}sqlite3_close(database);printf ("踢出完畢,已關(guān)閉數(shù)據(jù)庫(kù)\n");return;}}msg->cmd = 9003;write (client_socket, msg, sizeof(struct Msg));sqlite3_close(database);printf ("用戶不在線,修改失敗,已關(guān)閉數(shù)據(jù)庫(kù)\n"); }// 處理用戶操作請(qǐng)求函數(shù) void user_do (int client_socket) {struct Msg msg;int sig = 0;while(1){// 從客戶端讀一個(gè)結(jié)構(gòu)體數(shù)據(jù)int ret = read(client_socket, &msg, sizeof(msg));if (ret == -1){perror ("read");break;}// 代表客戶端退出if (ret == 0){printf ("客戶端返回登錄界面\n");break;}switch (msg.cmd){case 10: // 退出聊天室,返回登錄界面quit_chatroom(client_socket, &msg);sig = 1;break;case 1 : // 查看當(dāng)前在線人數(shù)display (client_socket, &msg);break;case 2 : // 處理群聊消息 chat1 (client_socket, &msg);break;case 3 : // 處理私聊消息 chat2 (client_socket, &msg);break; case 5 : // 處理確認(rèn)文件傳輸對(duì)象convey_confirm (client_socket, &msg);break;case 6 : // 更改密碼change_pass (client_socket, &msg);break;case 8 : // 處理在線注銷delete_user (client_socket, &msg);break;case 9005 : // 用戶不接受文件refuse (client_socket, &msg);break;case 9006 : // 用戶接受文件accept_ (client_socket, &msg);break;case 9007 : // 處理文件傳輸convey_chose (client_socket, &msg);break; case 9008 : // 文件傳輸完成convey_complete (client_socket, &msg);break;case 9011: // 處理禁言請(qǐng)求silent (client_socket, &msg);break;case 9012: // 處理解除禁言請(qǐng)求silent_del (client_socket, &msg);break;case 9013: // 處理踢出成員kickout (client_socket, &msg);break;}if (sig == 1){printf("即將退出普通用戶操作請(qǐng)求函數(shù)\n");break;}} }// 處理客戶端的登錄請(qǐng)求 void log_in(int client_socket, struct Msg *msg) {printf ("%s 請(qǐng)求登錄\n", msg->fromname);// 將用戶信息進(jìn)行比對(duì)// 打開(kāi)數(shù)據(jù)庫(kù)int ret = sqlite3_open("User.db", &database);if (ret != SQLITE_OK){printf ("打開(kāi)數(shù)據(jù)庫(kù)失敗\n");msg->cmd = -2;write (client_socket, msg, sizeof(struct Msg));return;}// 與User表中信息進(jìn)行比對(duì)char *errmsg = NULL;char **resultp = NULL;int nrow, ncolumn;char *sql = "select * from user";ret = sqlite3_get_table(database, sql, &resultp, &nrow, &ncolumn, &errmsg);if (ret != SQLITE_OK){printf ("數(shù)據(jù)庫(kù)操作失敗:%s\n", errmsg);msg->cmd = -1;write (client_socket, msg, sizeof(struct Msg));return;}int i;for (i = 0+ncolumn; i < (nrow+1)*ncolumn; i+=ncolumn){if(strcmp(resultp[i], msg->fromname)==0 && strcmp(resultp[i+1], msg->msg)==0){if (strcmp(resultp[i+3], "1") == 0){msg->cmd = -4;printf ("%s 已經(jīng)在別處登錄\n", msg->fromname);write (client_socket, msg, sizeof(struct Msg));sqlite3_free_table(resultp);// 關(guān)閉數(shù)據(jù)庫(kù)sqlite3_close(database);printf ("操作完成,已關(guān)閉數(shù)據(jù)庫(kù)\n"); return;}if (strcmp(resultp[i+4], "0") != 0){// 普通用戶msg->cmd = 1002;msg->sig = atoi(resultp[i+4]);printf ("普通用戶 %s 驗(yàn)證通過(guò)\n", msg->fromname);write (client_socket, msg, sizeof(struct Msg));}else {// 管理員msg->cmd = 1003;msg->sig = atoi(resultp[i+4]);printf ("管理員 %s 驗(yàn)證通過(guò)\n", msg->fromname);write (client_socket, msg, sizeof(struct Msg));} // 修改在線狀態(tài)、更新套接字char buf[100];errmsg = NULL;sprintf (buf, "update user set socket = '%d',flag = 1 where name = '%s'",client_socket,msg->fromname);ret = sqlite3_exec(database, buf, NULL, NULL, &errmsg);if (ret != SQLITE_OK){printf ("數(shù)據(jù)庫(kù)操作失敗:%s\n", errmsg);msg->cmd = -1;write (client_socket, msg, sizeof(struct Msg));return;}sqlite3_free_table(resultp);// 關(guān)閉數(shù)據(jù)庫(kù)sqlite3_close(database);printf ("在線狀態(tài)已更新,已關(guān)閉數(shù)據(jù)庫(kù)\n");printf ("進(jìn)入用戶操作請(qǐng)求處理功能\n");user_do (client_socket);return;}} printf ("%s 驗(yàn)證不通過(guò)\n", msg->fromname);msg->cmd = -3;write (client_socket, msg, sizeof(struct Msg));sqlite3_free_table(resultp);// 關(guān)閉數(shù)據(jù)庫(kù)sqlite3_close(database);printf ("操作完成,已關(guān)閉數(shù)據(jù)庫(kù)\n"); }// 處理客戶端的注冊(cè)請(qǐng)求 void reg(int client_socket, struct Msg *msg) {printf ("%s 進(jìn)行注冊(cè)\n", msg->fromname);// 將用戶進(jìn)行保存// 打開(kāi)數(shù)據(jù)庫(kù)int ret = sqlite3_open("User.db", &database);if (ret != SQLITE_OK){printf ("打開(kāi)數(shù)據(jù)庫(kù)失敗\n");msg->cmd = -2;write (client_socket, msg, sizeof(struct Msg));return;}// 往User表中添加信息char buf[100];char *errmsg = NULL;sprintf (buf, "insert into user values('%s','%s',%d,%d,%d)",msg->fromname,msg->msg,client_socket,0,msg->sig);ret = sqlite3_exec(database, buf, NULL, NULL, &errmsg);if (ret != SQLITE_OK){printf ("數(shù)據(jù)庫(kù)操作失敗:%s\n", errmsg);msg->cmd = -1;write (client_socket, msg, sizeof(struct Msg));return;}// 返回確認(rèn)信息msg->cmd = 1001;printf ("%s 注冊(cè)成功\n", msg->fromname);write (client_socket, msg, sizeof(struct Msg));// 關(guān)閉數(shù)據(jù)庫(kù)sqlite3_close(database);printf ("操作完成,已關(guān)閉數(shù)據(jù)庫(kù)\n"); }// 線程的工作函數(shù),即處理客戶端請(qǐng)求的函數(shù) void* hanld_client(void* v) {int client_socket = (int)v;struct Msg msg;while(1){printf("處理客戶端請(qǐng)求的函數(shù)函數(shù)已就緒\n");// 從客戶端讀一個(gè)結(jié)構(gòu)體數(shù)據(jù)int ret = read(client_socket, &msg, sizeof(msg));if (ret == -1){perror ("read");break;}// 代表客戶端退出if (ret == 0){printf ("客戶端退出\n");break;}switch (msg.cmd){case 1 : // 客戶端進(jìn)行注冊(cè)reg(client_socket, &msg);break;case 2 : // 客戶端進(jìn)行登錄log_in(client_socket, &msg);break;}}close (client_socket); }int main() {// 打開(kāi)數(shù)據(jù)庫(kù)User.dbint ret = sqlite3_open("User.db", &database);if (ret != SQLITE_OK){printf ("打開(kāi)數(shù)據(jù)庫(kù)失敗\n");return -1;}// 創(chuàng)建 user 表char *errmsg = NULL;char *sql = "create table if not exists user(name TEXT,password TEXT,socket INTEGER,flag INTEGER,sig INTEGER,primary key(name))";ret = sqlite3_exec(database, sql, NULL, NULL, &errmsg);if (ret != SQLITE_OK){printf ("數(shù)據(jù)庫(kù)操作失敗:%s\n", errmsg);return -1;}printf ("數(shù)據(jù)庫(kù)準(zhǔn)備就緒......\n");// 關(guān)閉數(shù)據(jù)庫(kù)sqlite3_close(database);// 初始化套接字int listen_socket = init_socket();while (1){// 獲取與客戶端連接的套接字int client_socket = MyAccept(listen_socket);// 創(chuàng)建一個(gè)線程去處理客戶端的請(qǐng)求,主線程依然負(fù)責(zé)監(jiān)聽(tīng)pthread_t id;pthread_create(&id, NULL, hanld_client, (void *)client_socket);pthread_detach(id); // 線程分離} close (listen_socket);return 0; }

總結(jié)

以上是生活随笔為你收集整理的网络编程项目(聊天室项目)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

国产成人一区在线 | 亚洲精品一区二区久 | 亚洲高清资源 | a亚洲视频 | 国产精品久久久久久久久久免费 | 午夜三级福利 | 操久久免费视频 | 日本精品xxxx | 久久亚洲美女 | 成人免费在线视频观看 | 天天草天天插 | 亚洲视频2| 亚洲精品久久久久久久不卡四虎 | 亚洲永久精品在线 | 国产精品成人自产拍在线观看 | 亚av在线 | 亚洲美女视频在线观看 | 久久69精品久久久久久久电影好 | 特级西西444www大精品视频免费看 | 13日本xxxxxⅹxxx20 | 精品国产免费人成在线观看 | 成人免费看电影 | 国产aaa免费视频 | 日韩午夜三级 | 免费av试看 | 中文字幕二区三区 | 一本一本久久a久久 | 亚洲国产播放 | 在线午夜电影神马影院 | 在线观看亚洲国产精品 | 亚洲精品国产第一综合99久久 | 在线看国产一区 | 九九九九九国产 | 麻豆视频免费入口 | 97超碰人人澡 | 波多野结衣视频在线 | 久久艹在线 | 欧洲在线免费视频 | 免费色视频网站 | 五月花丁香婷婷 | 久草在线免 | 97电影在线看视频 | 丁香激情综合久久伊人久久 | 中文字幕在线观看2018 | 美女视频一区 | 天天操天天摸天天爽 | 欧美性色综合网 | 国内一级片在线观看 | 久碰视频在线观看 | 国产婷婷在线观看 | 国产美腿白丝袜足在线av | 最新高清无码专区 | 一区av在线播放 | 久久综合电影 | 日日夜夜添| 色婷婷av在线 | 日韩视频一区二区在线观看 | 免费久久99精品国产 | 国产日韩中文在线 | 日韩电影精品一区 | 夜夜看av | 黄色软件视频网站 | 久久视讯| 国产视频91在线 | 中文字幕在线观看视频一区 | 特级西西444www大胆高清无视频 | 国产精品毛片久久久 | 91精品国产九九九久久久亚洲 | 在线看一区 | 超碰在线cao| 久久成年人网站 | 亚洲国产一区二区精品专区 | 国产精品一区二区 91 | 久久久www成人免费毛片麻豆 | 99精品视频在线观看视频 | 亚洲欧美激情插 | 天天操天天干天天摸 | 99热这里精品 | 香蕉视频网址 | 狠狠干夜夜爱 | 日日夜夜草 | 亚洲精品在线观看中文字幕 | 欧亚久久 | 成年人在线 | av三区在线| 99视频国产精品免费观看 | av天天澡天天爽天天av | 亚洲激情综合 | 日韩在线视频免费观看 | 婷婷六月天在线 | 国产精品久久久久久久久免费 | 激情av资源网| 亚洲精品一区二区网址 | 8x成人免费视频 | 日韩高清一 | 精品美女在线视频 | 香蕉在线影院 | 中文字幕在线人 | 欧美极品少妇xbxb性爽爽视频 | 日韩高清免费在线 | 亚洲毛片视频 | 日韩无在线| 国产精品久久久久久爽爽爽 | 7777xxxx| 天天色天天射天天干 | 91在线看黄 | 成人资源在线 | 久精品在线 | 久久丁香网| 日韩欧美一二三 | 亚洲国产影院 | 成人影视免费 | 成年人视频在线观看免费 | 亚洲狠狠操 | 四虎影视4hu4虎成人 | 香蕉97视频观看在线观看 | 精品国产1区 | 亚洲成人黄 | 久久一区国产 | 国产精品视频最多的网站 | 久久精品超碰 | 99精品欧美一区二区三区 | 最新午夜 | 激情欧美丁香 | 在线小视频你懂得 | 久热国产视频 | 狠狠干 狠狠操 | 91视频久久 | 欧美a免费 | 中文资源在线播放 | 欧美精品国产综合久久 | 国产高清视频在线免费观看 | 91久久国产自产拍夜夜嗨 | 免费国产亚洲视频 | 中日韩欧美精彩视频 | 久久精品一二三区白丝高潮 | 日本乱码在线 | 国产精品成人久久久久 | 久久久久五月天 | 国产96在线视频 | www.久久99 | 亚洲国产精久久久久久久 | 最新高清无码专区 | 国产又粗又猛又爽又黄的视频免费 | 日韩欧美亚州 | 日韩不卡高清视频 | 久久综合干 | 久久国产精品成人免费浪潮 | 久久精品视频播放 | 国产乱对白刺激视频不卡 | av大片免费在线观看 | 久久久久国产精品厨房 | 日韩一级片观看 | 日本韩国中文字幕 | 99免费在线 | 久久一区精品 | 少妇自拍av| 91黄色小视频 | 久久精品波多野结衣 | 久久久精品综合 | 成年人天堂com | 午夜精品久久久久久 | 久热这里有精品 | 婷婷丁香久久五月婷婷 | 国产精品一区二区免费 | 免费情缘| 在线观看国产中文字幕 | 麻花豆传媒一二三产区 | 99视频精品免费观看, | 色www精品视频在线观看 | av在线官网 | 国产成人黄色av | 一区二区三区四区影院 | 国产vs久久 | 99精品视频免费观看视频 | 久久久国产一区二区三区 | 精品亚洲va在线va天堂资源站 | 亚洲第一中文字幕 | 国产一二三区在线观看 | 日本色小说视频 | 不卡中文字幕在线 | 在线小视频 | 91亚洲在线观看 | 激情偷乱人伦小说视频在线观看 | 国产一区欧美二区 | 国产高清视频免费最新在线 | 婷婷99 | 97在线免费 | 久草在线一免费新视频 | 日韩专区一区二区 | 久久激情婷婷 | 91精品国产综合久久福利不卡 | 国产1区2 | 丁香资源影视免费观看 | 五月天狠狠操 | 天天搞天天| 丰满少妇一级 | 国产丝袜在线 | 国产另类av | 亚洲国产片色 | 中文字幕在线播出 | 91亚洲在线| 99爱在线| 中文一区二区三区在线观看 | 欧美精品久久久久久久久老牛影院 | 国产男男gay做爰 | 国产精品一区二区视频 | 国产成人在线综合 | 欧美精品在线观看免费 | 成人av直播| 欧美精品久久人人躁人人爽 | 国产在线精品一区二区三区 | av网站免费看 | 麻豆影视在线免费观看 | 91精品在线观看入口 | 成人黄色大片在线免费观看 | 91视频免费看 | 色网站在线 | 久久男人视频 | 欧美日韩精品久久久 | 免费高清影视 | 欧美成人性网 | 国产精品一级在线 | 国产视频每日更新 | 91传媒在线播放 | www日韩在线观看 | 欧美99久久 | 91香蕉国产在线观看软件 | 最新不卡av| 日韩精品视频久久 | 国产区第一页 | 国产黄色免费看 | 国产视频一区二区在线播放 | 中文在线字幕观看电影 | 国产精品久99 | 成年人免费看片网站 | 国产福利av在线 | 九九激情视频 | 91在线精品播放 | 婷婷综合网 | 狠狠色噜噜狠狠狠狠2021天天 | 国内丰满少妇猛烈精品播放 | 激情在线网站 | 久久久久亚洲精品男人的天堂 | av专区在线 | 国产免费又爽又刺激在线观看 | 在线免费视频 你懂得 | 久久只有精品 | 黄网站app在线观看免费视频 | 99久高清在线观看视频99精品热在线观看视频 | 欧美日韩免费一区 | 国产日韩欧美自拍 | 黄色片网站免费 | 日韩av电影中文字幕在线观看 | 国产精品视频免费 | 国产精品一区二区你懂的 | 中文字幕a∨在线乱码免费看 | 欧美精品久久久久久久久免 | 国产精品欧美日韩在线观看 | 日韩免费b | 五月天亚洲综合 | 国产麻豆视频免费观看 | 欧美a级免费视频 | 五月婷香蕉久色在线看 | 日三级在线 | 久草在线视频网站 | 97伊人网 | 日韩精品观看 | 一级淫片a | 国产精品99久久久久 | 香蕉在线观看 | 99免费在线观看视频 | 国产成人一区二区三区影院在线 | 人人人爽 | 91高清免费 | 天天色宗合| 亚洲精品在 | 97在线视频免费 | 最新av观看| www.午夜视频| 九九99靖品| 91中文字幕永久在线 | 久久综合免费 | 国产精品美女久久久久久久网站 | 国产中文字幕三区 | 成人免费在线观看电影 | 91精品在线免费观看视频 | 黄色av电影免费观看 | 成人三级视频 | 欧美动漫一区二区三区 | 精品久久一区二区三区 | 最近2019年日本中文免费字幕 | 日韩高清在线一区二区三区 | 日韩在线视频在线观看 | 2021国产视频 | 一本一本久久a久久精品综合小说 | 亚洲综合在线一区二区三区 | 亚洲成人av一区 | 天天综合日日夜夜 | 亚洲国产日韩一区 | 日韩高清免费无专码区 | 色综合婷婷久久 | 99久久国产免费免费 | av在线免费播放 | 久久精品网址 | 国产精品入口a级 | 日产乱码一二三区别免费 | 激情伊人五月天久久综合 | 亚洲精品国产精品乱码不99热 | 蜜桃视频成人在线观看 | 久久精品站 | 国产精品一区免费观看 | 黄网站色 | 日日夜夜骑| 日韩av中文| 九色在线视频 | 最近日本韩国中文字幕 | 在线观看黄 | 91桃色在线免费观看 | 99久久精品久久久久久清纯 | 国产婷婷vvvv激情久 | 在线一区二区三区 | 奇米影视777四色米奇影院 | 成 人 黄 色 视频免费播放 | 欧美一级专区免费大片 | 免费精品国产 | 欧美成人h版电影 | 亚洲精品合集 | 久久久国际精品 | 91精品国产欧美一区二区 | 婷婷丁香花五月天 | 亚洲,国产成人av | 天天做天天爱天天爽综合网 | 人操人| 亚洲激情小视频 | 99热精品在线观看 | 在线黄色免费av | 五月天亚洲激情 | 国产护士av| 中文一区在线 | 国产xvideos免费视频播放 | 日日干激情五月 | 又黄又爽又色无遮挡免费 | 婷婷六月激情 | 一本—道久久a久久精品蜜桃 | 99一级片 | 亚洲高清精品在线 | 国产在线无 | 国产精品专区在线观看 | 亚洲91中文字幕无线码三区 | 九九99| 狠狠操天天射 | 五月天久久久久 | 国产精品高清免费在线观看 | 黄色一级大片在线免费看国产一 | 玖玖玖影院 | 韩国av电影在线观看 | 四虎影视国产精品免费久久 | 久久久久国产视频 | 国产 在线 高清 精品 | 亚洲国产视频在线 | 伊人色综合久久天天 | 亚洲人成人在线 | 久久99婷婷 | 国产精品日韩久久久久 | 国产精品久久久免费 | 国产精品原创av片国产免费 | 久久精品一区二 | 天天干夜夜擦 | 福利精品在线 | 91麻豆精品 | 亚洲精品乱码久久久久久蜜桃不爽 | 久久久91精品国产一区二区精品 | 在线高清av| 伊人天天综合 | 国产三级国产精品国产专区50 | 免费高清在线观看成人 | 99热最新在线 | 91精品在线看 | 欧美久久久久久久久久久 | 欧美日韩国产一区二 | 色播五月激情综合网 | 国产理论影院 | 蜜臀av麻豆 | 综合色在线 | 久久精品超碰 | av黄网站| 免费看污片 | 国内精品福利视频 | 91久久精品一区二区二区 | 久久久天堂| 麻豆视频在线免费观看 | 999电影免费在线观看 | 久久成人福利 | 亚洲无吗视频在线 | 久草在线电影网 | www.婷婷色 | 久久视频这里有精品 | 高清在线一区二区 | 亚洲无在线 | 亚洲欧美日韩中文在线 | 在线观看一区视频 | 伊人首页 | 在线91视频 | 国产a级精品 | 午夜性生活片 | 欧美日韩国产xxx | 人人爽人人香蕉 | 免费av片在线 | 久久久久久蜜桃一区二区 | 五月婷久久 | 国产精品色在线 | 国产精品视频在线看 | 超碰99在线 | 五月天网站在线 | 91九色精品女同系列 | 精品一区二区在线看 | 美女国产在线 | 天天干天天搞天天射 | 激情久久综合网 | 中文字幕国产在线 | 麻豆一精品传二传媒短视频 | 天天操夜 | 国产一线二线三线性视频 | 91香蕉视频在线 | av不卡中文字幕 | 深夜福利视频在线观看 | 久久久免费精品国产一区二区 | av电影av在线 | 欧美成人999 | 国产精品美女久久久久久久久久久 | 五月开心六月婷婷 | 丰满少妇在线观看资源站 | 亚洲国内精品视频 | 国产中文视| 国产黄免费在线观看 | 丁香六月婷婷开心 | 欧美最猛性xxxxx(亚洲精品) | 色综合亚洲精品激情狠狠 | 黄网av在线 | 精品在线播放视频 | 又黄又网站| 久久久久国| 亚洲国产成人精品久久 | 免费一级片在线 | 黄色精品免费 | 最新日韩在线观看视频 | 婷婷色视频| 亚洲成人av在线 | 久久综合九色综合久久久精品综合 | 国产精品自拍在线 | 91精品免费看 | 国产精品美女久久久久久 | 手机看片国产日韩 | 久操伊人| 久久精品官网 | 色婷婷中文 | 日本在线观看一区 | 免费av成人在线 | 久草国产在线观看 | 91精品久久久久久粉嫩 | 国产成人精品亚洲日本在线观看 | 精品五月天 | 色网站在线看 | 日日夜夜爱 | 天天综合导航 | 免费观看一级成人毛片 | 久久久免费播放 | 国产视频在线播放 | 成人久久18免费网站麻豆 | 五月天久久久久 | 在线 国产 亚洲 欧美 | 午夜视频在线瓜伦 | 精品国产一区二区三区男人吃奶 | 亚洲美女在线一区 | 激情av五月婷婷 | 一区二区视频在线观看免费 | 亚洲精品456在线播放乱码 | 日韩美视频 | 国内一区二区视频 | 国产精品毛片久久久久久久 | 国产一区二区在线免费播放 | 亚洲一区二区观看 | 欧美a级在线 | 在线一区二区三区 | 久久久久久久影院 | 少妇bbw搡bbbb搡bbb | 97香蕉视频| 亚洲一区av| 亚洲涩涩一区 | 96久久久| 国内精品一区二区 | 色播六月天 | 在线视频18在线视频4k | 国产97在线播放 | 四虎国产精品永久在线国在线 | 国产一级视屏 | 国偷自产中文字幕亚洲手机在线 | 日韩中文在线字幕 | 中文字幕一区二区三 | 91色在线观看视频 | 特级xxxxx欧美 | 国产精品一区二区久久精品 | 亚洲欧洲一区二区在线观看 | 中文字幕在线播放视频 | 久久久久久久久久久久久9999 | 久久免费电影网 | 高清不卡免费视频 | 中文字幕亚洲欧美 | 国产最新在线视频 | 插婷婷| 91在线在线观看 | av一区在线播放 | 久草视频在线新免费 | 久久久国产一区 | 午夜精品久久久久久久久久 | 国产精品69久久久久 | 日韩欧美电影在线观看 | 色久av| 欧美成人中文字幕 | 国产精品一二 | 91爱爱网址 | 久草在线这里只有精品 | 欧美精品首页 | 色偷偷av男人天堂 | 免费午夜网站 | 狠狠色香婷婷久久亚洲精品 | 成人黄色在线观看视频 | 久久99深爱久久99精品 | 国产伦精品一区二区三区高清 | 国产粉嫩在线观看 | 中文字幕中文字幕在线中文字幕三区 | 国产在线精品一区二区 | 亚洲视频精品 | 中文字幕av日韩 | 国产中文在线播放 | 亚洲国产成人精品久久 | 国产在线污| 日韩精品五月天 | 国产一区免费视频 | 欧美日韩有码 | 久草在线电影网 | 中文字幕欧美激情 | 在线观看成年人 | 欧美激情第八页 | 久久99网| 狠狠夜夜 | 久久高清免费视频 | 国产精品高清一区二区三区 | 欧美黑人性爽 | 国产黄色片在线免费观看 | 99久久精品日本一区二区免费 | 久久成人毛片 | 国产第一页在线观看 | 欧美成人黄色片 | 亚洲国产精品va在线看黑人 | 在线播放视频一区 | 91视频在线免费下载 | 亚洲,国产成人av | 国产亚洲免费观看 | 最新国产精品拍自在线播放 | 在线国产专区 | 欧美a视频在线观看 | 中国黄色一级大片 | 午夜私人影院 | 精品久久久久久久久久岛国gif | 欧美人zozo | 成人av免费在线观看 | 日韩av午夜 | 国产精品久久久久av免费 | 日韩精品欧美精品 | 国产小视频你懂的 | 婷婷综合久久 | 蜜臀av在线一区二区三区 | 国产一区二区播放 | 中文在线亚洲 | 五月婷婷一级片 | a级片久久久 | 日韩性xxxx| 色综合综合 | 国产精品麻豆99久久久久久 | 国产精品美女在线 | 亚洲精品小视频在线观看 | 国产中文字幕国产 | 久草视频精品 | 日韩精品欧美专区 | 日韩电影一区二区三区在线观看 | 日韩在线视频看看 | 日韩精品视频免费专区在线播放 | 日日夜夜天天久久 | 国产日韩精品一区二区在线观看播放 | 日韩黄色免费看 | 亚洲精品乱码久久久久久 | 在线观看精品一区 | 久草免费在线观看视频 | 欧美一区三区四区 | 欧美成人在线免费 | 伊人丁香 | 色综合天天干 | av中文电影 | 免费在线91 | 狠狠狠狠狠狠 | 97视频人人澡人人爽 | 亚洲免费国产视频 | 在线观看中文字幕av | 亚洲v欧美v国产v在线观看 | 国产一卡久久电影永久 | 久草男人天堂 | 国产成人精品电影久久久 | 中文字幕一区二区三区视频 | 欧美作爱视频 | 亚洲人人精品 | 成人va视频 | 日韩91在线 | 久久视频免费 | 久久天天躁狠狠躁亚洲综合公司 | 日韩最新在线视频 | 日日夜夜av | 国产直播av| 在线看91| 日韩欧美99 | 中文字幕在线视频一区 | 日韩精品一区电影 | 欧美大片在线观看一区 | 午夜久操| 天天干,夜夜爽 | 九九九在线观看 | 五月婷婷久草 | 中文久久精品 | 国产999精品 | 波多野结衣一区二区 | 91av在线免费视频 | 国产又粗又猛又黄又爽视频 | 国产1区2区3区在线 亚洲自拍偷拍色图 | 欧美精品久久久久久久亚洲调教 | 天天视频亚洲 | 亚州av一区 | 黄色av大片 | 日韩在线电影一区 | 久久免费成人网 | 亚洲成av人片在线观看无 | 国产女人18毛片水真多18精品 | 亚洲dvd| 九九国产精品视频 | 99视频国产在线 | 丰满少妇高潮在线观看 | 人人精品 | 亚洲视频www | 亚洲精品18日本一区app | 国偷自产中文字幕亚洲手机在线 | 午夜精品久久久久久久99婷婷 | 日韩精品免费一区二区三区 | 中文字幕在线观看免费观看 | 永久免费的av电影 | 爱干视频 | 国产夫妻av在线 | 国产精品黑丝在线观看 | 亚洲视频axxx | 成年人毛片在线观看 | 9在线观看免费高清完整版在线观看明 | 综合久久精品 | av综合在线观看 | 97精品国产91久久久久久久 | 超碰在线亚洲 | 一本一道久久a久久综合蜜桃 | 狠狠地操 | 青青草国产精品 | 国产乱对白刺激视频不卡 | 国产淫片免费看 | 日韩欧美视频一区二区三区 | 日韩精品三区四区 | 亚洲精品人人 | 婷婷在线免费 | 免费在线看v | 六月丁香婷婷网 | 人成午夜视频 | 夜夜躁日日躁狠狠久久av | 中文字幕一区二区三区在线播放 | 成人在线黄色电影 | 黄色av网站在线免费观看 | 亚洲精品一区二区精华 | 99精品一区二区三区 | 黄色av一级 | 人人舔人人射 | 亚洲精品高清视频 | 正在播放国产一区 | 射综合网| 91人人人 | 日韩一级片观看 | 午夜视频免费在线观看 | 久久国产精品免费一区二区三区 | 久久婷婷色综合 | 在线看日韩av | 亚洲国产成人久久综合 | 日韩免费 | 日本黄色大片免费看 | 亚洲精品国产自产拍在线观看 | 成人久久电影 | 欧美午夜理伦三级在线观看 | www.狠狠 | 久久久久亚洲最大xxxx | 免费三级大片 | 九九综合九九 | 狠狠操操网| 亚洲欧美成aⅴ人在线观看 四虎在线观看 | 最近中文字幕在线 | 干综合网| 国产精品麻 | 蜜臀av性久久久久蜜臀aⅴ涩爱 | 国产一卡在线 | 在线观看深夜视频 | 久久精品99国产精品酒店日本 | 在线看的av网站 | 8x8x在线观看视频 | 国产精品资源在线观看 | 视频一区二区三区视频 | 日韩一区二区三区在线观看 | 亚洲午夜久久久久久久久久久 | 四虎影视成人永久免费观看亚洲欧美 | 久久99视频免费观看 | 亚洲欧美国产视频 | 在线观看中文字幕网站 | 午夜精品久久久 | 日本高清免费中文字幕 | 色综合久久综合 | 国产一区二区三区四区在线 | 99久热在线精品视频 | 日韩免费小视频 | 992tv在线 | 国产亚洲精品久久久久久网站 | 久久久精品电影 | 免费又黄又爽的视频 | 欧美另类tv | 久久伦理电影网 | 福利视频区| 国产精品一区二区三区视频免费 | 亚洲免费一级电影 | 久久久久久久国产精品视频 | 五月婷网 | 伊人色播 | 天天艹天天爽 | 亚洲国产三级在线 | av在线播放国产 | 精品视频在线播放 | 狠狠色狠狠色综合系列 | 国产日本在线观看 | 欧美人体xx | 亚洲久草网 | 日韩综合精品 | 亚洲影院国产 | 亚洲激情校园春色 | www.xxx.性狂虐 | 91看片淫黄大片一级在线观看 | 中文字幕一区二区三区乱码在线 | 亚洲欧美综合 | 久久99精品国产一区二区三区 | 99久久精品免费看国产 | 成人性生交大片免费看中文网站 | 久久综合欧美 | 91精品办公室少妇高潮对白 | 91香蕉视频污在线 | 一区二区在线影院 | 91av视频在线播放 | av福利第一导航 | 精品久久久国产 | 四虎天堂 | 特级毛片在线免费观看 | 亚洲精品456在线播放乱码 | 一区二区三区四区五区在线 | 久久伦理 | 六月天综合网 | 欧美激情视频免费看 | 欧美福利精品 | 久久99精品视频 | 中文在线字幕免费观 | 韩国三级av在线 | www.久久成人| 国产三级午夜理伦三级 | 美女视频久久黄 | av中文字幕在线观看网站 | 五月婷婷一区二区三区 | 亚洲在线网址 | 中文字幕在线日 | 免费精品国产 | 伊人电影在线观看 | 日韩欧美极品 | 国产视频中文字幕在线观看 | 欧美a级在线 | 黄a在线观看 | 天天操天天草 | 午夜精品在线看 | 婷婷在线观看视频 | 久久99国产精品久久99 | 日韩三级成人 | 日韩亚洲国产精品 | 日韩黄色一级电影 | 日本三级久久久 | 久久艹精品| 日韩视频免费 | 国产一区二区三区在线免费观看 | 在线 国产 日韩 | 日韩电影中文,亚洲精品乱码 | 黄色片网站 | 久久精品亚洲国产 | 国产亚洲成av人片在线观看桃 | 天天综合网 天天综合色 | 一级片视频在线 | 麻花传媒mv免费观看 | 天堂av高清 | 香蕉视频在线视频 | 国产亚洲视频系列 | 欧美日韩不卡在线视频 | 91资源在线视频 | 久久热首页| 色婷婷九月 | www.夜夜爽 | 国产精品正在播放 | 超碰最新网址 | 麻豆免费视频观看 | 激情欧美一区二区三区 | 日韩欧美国产激情在线播放 | 91精品国产综合久久久久久久 | 国产欧美精品一区aⅴ影院 99视频国产精品免费观看 | 午夜性色 | 国产视频资源在线观看 | 日韩精品在线观看av | 91综合视频在线观看 | 国产在线日韩 | 日韩黄色大片在线观看 | 国产盗摄精品一区二区 | 日本在线h| 天堂av色婷婷一区二区三区 | 狠狠地操| 日韩在线视频观看免费 | 六月婷婷网 | 成人国产精品久久久久久亚洲 | 天天做天天射 | 欧美成人一区二区 | 国产特级毛片aaaaaaa高清 | 国产黄在线播放 | 青春草免费在线视频 | 国模精品一区二区三区 | 亚洲人成免费 | 在线日本看片免费人成视久网 | 欧美日韩国产综合一区二区 | 国产无吗一区二区三区在线欢 | 欧美日韩a视频 | 不卡电影一区二区三区 | 热久久免费视频 | 日韩午夜av | 97福利社| 久久毛片高清国产 | 久草在线一免费新视频 | 91九色免费视频 | 人人躁| 国产精品v欧美精品v日韩 | 欧美一二三在线 | 91热这里只有精品 | 亚洲成人免费 | 91字幕 | 在线欧美最极品的av | 在线 国产 亚洲 欧美 | 国精产品满18岁在线 | 久久国产精品一二三区 | 新版资源中文在线观看 | 综合网婷婷 | 成人国产精品电影 | 日韩高清一区二区 | 日韩在线观看小视频 | 伊人天天狠天天添日日拍 | 色五月激情五月 | 精品一区二区免费视频 | 亚洲每日更新 | 一区二区三区av在线 | 日韩理论在线播放 | 欧美一级片播放 | 最近2019年日本中文免费字幕 | 日韩二区在线观看 | 中文字幕在线国产 | 99热这里只有精品免费 | 狠狠狠狠狠操 | 国产在线观看网站 | 日韩视频一区二区三区在线播放免费观看 | 国产一区二区三区午夜 | bbbbb女女女女女bbbbb国产 | 亚洲九九精品 | www日日 | 国产又粗又硬又爽的视频 | 中文字幕一区二区在线观看 | 香蕉在线观看 | 人人玩人人添人人 | 亚洲va天堂va欧美ⅴa在线 | 日韩专区 在线 | 在线观看国产日韩 | 午夜精品久久久久久久久久久 | 日韩精品一区二区三区免费观看视频 | 国产精品电影在线 | 色播五月婷婷 | 久草影视在线观看 | 国产精品久久久久四虎 | 亚洲欧美日韩国产 | 欧美少妇影院 | 91九色porny蝌蚪视频 | 日韩精品视频免费看 | 欧美激情综合五月 | 又黄又爽的视频在线观看网站 | 国产精品久久久久久久久久久久久久 | 人人射人人射 | 日韩乱码在线 | 美女av免费 | 天天综合成人 | 日韩中文字幕在线看 | 成人精品一区二区三区中文字幕 | 色婷婷导航 | 久久乱码卡一卡2卡三卡四 五月婷婷久 | 日日夜夜婷婷 | 日韩在线视频免费观看 | 久久久久国产免费免费 | 人人干狠狠干 | 91精品欧美 | 国产精品久久久久久久久久久久午夜 | 日韩乱理 | 国产欧美久久久精品影院 | av天天在线观看 | 日日夜夜精品免费视频 | 久久中文字幕在线视频 | 日本黄色免费看 | www.午夜色.com | 亚洲最大成人网4388xx | 天天曰夜夜爽 | 天天操夜夜看 | 久久特级毛片 | 天堂av免费观看 | 久久免费看av | 中文字幕网站视频在线 | 国产一区二区成人 | 日韩一区二区三区在线看 | 成人国产精品免费观看 | 久草在线官网 | 精品夜夜嗨av一区二区三区 | 日韩激情三级 | 天天摸天天干天天操天天射 | 国产 av 日韩 | 日韩av电影手机在线观看 | 久久成人欧美 | 在线看的毛片 | 亚洲精品播放 | 最近中文字幕高清字幕在线视频 | 久久avav| 麻豆视频国产 | 91九色蝌蚪在线 | 9999精品视频 | 精品中文字幕视频 | 国产成人精品日本亚洲999 | 国产精品欧美久久久久久 | 色婷婷九月 | 国产亚洲永久域名 | 欧美精品三级在线观看 | 亚洲日本色 | 黄色tv视频 | 国产高清视频在线观看 | 伊人五月天综合 | 久久国产精品免费观看 | 成人久久精品视频 | 天天干干 | 99精品福利| 综合网av| 国产精品免费在线播放 | 麻豆91在线 | 中文字幕你懂的 | 久久 在线 | 国产精品手机视频 | 久草在线官网 | 狠狠色2019综合网 | 国产成人久久av977小说 | 天天天天综合 | 伊人永久 | 国产精品日韩在线 | 天天操夜操视频 | 91中文字幕在线 | 国产亚洲视频系列 | 日韩精品一区二区三区在线视频 | 少妇bbb搡bbbb搡bbbb | 亚一亚二国产专区 | 亚洲韩国一区二区三区 | 国产精品第54页 | 日韩美女免费线视频 | 高清av中文在线字幕观看1 | 就操操久久 | 亚洲国产精品成人av | 日韩精品中文字幕在线观看 | 成人免费在线视频 | 亚洲成人午夜av | 久久精品日产第一区二区三区乱码 | 麻花豆传媒一二三产区 | 亚洲精品 在线视频 | 国产福利小视频在线 | 人人爽爽人人 |