1. 程式人生 > >網路程式設計專案(聊天室專案)

網路程式設計專案(聊天室專案)

一、實現目標

一個在Linux下可以使用的聊天軟體,要求至少實現如下功能:
1. 採用Client/Server架構
2. Client A 登陸聊天伺服器前,需要註冊自己的ID和密碼
3. 註冊成功後,Client A 就可以通過自己的ID和密碼登陸聊天伺服器
4. 多個Client X 可以同時登陸聊天伺服器之後,與其他使用者進行通訊聊天
5. Client A 成功登陸後可以檢視當前聊天室內其他子啊先使用者Client x
6. Client A 可以選擇發訊息給某個特定的 Client x,即“悄悄話”功能
7. Client A 可以選擇發訊息給全部的線上使用者,即“群發訊息”功能
8. Client A 在退出時需要儲存聊天記錄
9. Server 端維護一個所有登陸使用者的聊天會的記錄檔案,以便檢視

可以選擇實現的附加功能:
1. Server 可以內建一個特殊許可權的賬號admin,用於管理聊天室
2. Admin 可以將某個Client X“踢出聊天室”
3. Admin 可以將某個Client X“設為只能旁聽,不能發言”
4. Client 端發言增加表情符號,可以設定某些自定義的特殊組和來表達感情,如輸入:),則會自動傳送“XXX向大家做了個笑臉”
5. Client 段增加某些常用話語,可以對其中某些部分進行“姓名替換”,例如,輸入/ClientA/welcome,則會自動傳送“ClientA大俠,歡迎你來到咱們的聊天室”
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 9999
char myName[20]; // 儲存使用者名稱 char msg1[1024]; // 儲存聊天資訊 sqlite3 * database; int flag1 = 0; // 執行緒退出的判斷條件(不退出) int flag2 = 0; // 檔案傳輸確認訊號(無接收) int flag3 = 0; // 存在檔案接收請求的判斷(不存在) int flag4 = 0; // 本地儲存是否被禁言(未被禁言) // 協議 struct Msg { char msg[1024]; // 訊息內容 int cmd; // 訊息型別 char filename[50]; // 儲存檔名 char toname[20]; // 接收者姓名 char fromname[20]; // 傳送者姓名 int sig; // 使用者狀態(0:管理員、1:普通使用者、2:被禁言) }; struct Msg msg; // 全域性變數兩個執行緒共享 // 註冊/登入介面 void interface1() { system("clear"); printf ("\t*************************** 網路聊天室 *****************************\n"); printf ("\t* *\n"); printf ("\t* *\n"); printf ("\t* 1、 註冊 *\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***** 請輸入命令: "); } // 普通使用者介面 void interface2() { system("clear"); printf ("\t*************************** 網路聊天室 *****************************\n"); printf ("\t* *\n"); printf ("\t* *\n"); printf ("\t* 1、 檢視當前線上人數 *\n"); printf ("\t* 2、 進入群聊介面 *\n"); printf ("\t* 3、 進入私聊介面 *\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***** 請輸入命令: "); } // 管理員介面 void interface3() { system("clear"); printf ("\t*************************** 網路聊天室 *****************************\n"); printf ("\t* *\n"); printf ("\t* *\n"); printf ("\t* 1、 檢視當前線上人數 *\n"); printf ("\t* 2、 進入群聊介面 *\n"); printf ("\t* 3、 進入私聊介面 *\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***** 請輸入命令: "); } // 用來儲存收到的聊天資訊 void keep_msg(char * msg1) { // 開啟資料庫 int ret = sqlite3_open("Histroy.db", &database); if (ret != SQLITE_OK) { printf ("\t開啟資料庫失敗\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資料庫操作失敗:%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); } // 用來監聽收到的資訊 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, "收到一條來自%s的群訊息:\n\t%s", msg.fromname,msg.msg); printf ("\n\n\t%s\n", msg1); printf ("\n\t回車鍵返回 \n"); keep_msg (msg1); break; case 9002: // 私聊 printf ("\n\t%s 發來一條訊息:\n\t%s\n", msg.fromname, msg.msg); sprintf (msg1,"%s 向 %s 傳送一條資訊:\n\t%s",msg.fromname, msg.toname, msg.msg); printf ("\n\t回車鍵返回 \n"); keep_msg (msg1); break; case 9003: // 處理髮送失敗 sleep(3); printf ("\n\t使用者不線上或不存在,傳送失敗\n"); printf ("\n\t回車鍵返回 \n"); break; case 9004: // 是否存在檔案接收確認訊號 printf ("\n\n\t收到一條資訊,輸入任一字元進行回覆:"); fflush(stdout); flag3 = 1; break; case 9005: // 檔案傳輸請求被拒絕 printf ("\n\t您傳送的檔案傳輸請求已被拒絕\n"); printf ("\n\t回車鍵返回 \n"); break; case 9006: // 檔案傳輸請求已通過 printf ("\n\t您傳送的檔案傳輸請求已通過,請開啟檔案傳輸介面進行檔案傳輸\n"); printf ("\n\t回車鍵返回 \n"); break; case 9007: // 接收檔案 if (flag2 != 1) printf ("\n\t已成功攔截 %s 給您傳送的檔案\n", msg.fromname); else receive(); break; case 9008: // 檔案傳輸完成 printf ("\n\t%s 給您傳送的檔案已全部接收完畢,請及時檢視\n", msg.fromname); printf ("\n\t回車鍵返回 \n"); flag2 = 0; // 重置檔案傳輸確認訊號 break; case 9009: // 密碼修改成功 printf ("\n\t密碼修改成功!\n"); sleep(1); break; case 9010: // 密碼輸入有誤 printf ("\n\t密碼輸入有誤,修改失敗\n"); usleep(1500000); break; case 9011: // 收到禁言訊號 printf ("\n\t您已被管理員禁言,將無法傳送群聊資訊\n"); printf ("\n\t回車鍵返回 \n"); flag4 = 1; break; case 9012: // 收到結除禁言訊號 printf ("\n\t您已被管理員解除禁言\n"); printf ("\n\t回車鍵返回 \n"); flag4 = 0; break; case 9013: // 收到被踢出訊號 printf ("\n\t您已被管理員踢出,即將退出聊天室....\n"); //sleep (2); flag1 = 1; break; } usleep(400000); } } // 檢視當前線上人數 void display (int socketfd) { msg.cmd = 1; write (socketfd, &msg, sizeof(struct Msg)); //向伺服器傳送請求 usleep(100000); printf ("\n\t當前線上人數為:%d\n", msg.cmd); printf ("\n\t回車鍵返回 \n"); getchar(); } // 退出聊天室,返回登入介面 void quit_chatroom (int socketfd) { msg.cmd = 10; strcpy (msg.fromname, myName); write (socketfd, &msg, sizeof(struct Msg)); //向伺服器傳送退出訊號 } // 進入群聊介面 void chat1(int socketfd) { if (flag4 == 1) { printf ("\n\t您已被管理員禁言,無法傳送群聊資訊...\n"); return; } msg.cmd = 2; strcpy (msg.fromname, myName); strcpy(msg.toname, "all"); printf ("\n\t請輸入您要傳送的內容:\n\t"); scanf ("%s",msg.msg); getchar(); write (socketfd, &msg, sizeof(struct Msg)); //向伺服器傳送請求 printf ("\n\t傳送完成,等待處理結果.....\n"); // usleep (500000); } // 進入私聊介面 void chat2(int socketfd) { msg.cmd = 3; strcpy (msg.fromname, myName); printf ("\n\t請輸入您要傳送的物件:\n\t"); scanf ("%s",msg.toname); getchar(); printf ("\t請輸入您要傳送的內容:\n\t"); scanf ("%s",msg.msg); getchar(); write (socketfd, &msg, sizeof(struct Msg)); //向伺服器傳送請求 printf ("\n\t傳送完成,請稍候.....\n"); usleep (500000); } // 列印群聊歷史記錄 void chat1_hst() { system("clear"); printf ("\t*************************** 網路聊天室 *****************************\n\n\n"); printf ("\t群聊歷史記錄: \n"); // 開啟資料庫 int ret = sqlite3_open("Histroy.db", &database); if (ret != SQLITE_OK) { printf ("\t開啟資料庫失敗\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 ("資料庫操作失敗:%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); // 關閉資料庫 sqlite3_close(database); } // 列印私聊歷史記錄 void chat2_hst() { system("clear"); printf ("\t*************************** 網路聊天室 *****************************\n\n\n"); printf ("\t私聊歷史記錄:\n"); // 開啟資料庫 int ret = sqlite3_open("Histroy.db", &database); if (ret != SQLITE_OK) { printf ("\t開啟資料庫失敗\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 ("資料庫操作失敗:%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); // 關閉資料庫 sqlite3_close(database); } // 檢視聊天記錄 void dis_histroy(int socketfd) { printf ("\n\t a、檢視群聊記錄\n\t b、檢視個人聊天記錄\n\t"); printf ("\n\t***** 請選擇: "); switch (getchar()) { case 'a': chat1_hst(); break; case 'b': chat2_hst(); break; } printf ("\n\t回車鍵返回 "); getchar(); } // 確認傳輸物件 void convey_confirm(int socketfd) { msg.cmd = 5; strcpy (msg.fromname, myName); printf ("\n\t請輸入檔案的傳輸物件:\n\t"); scanf ("%s",msg.toname); getchar(); printf ("\n\t傳輸請求傳送完成,請稍等.....\n"); write (socketfd, &msg, sizeof(struct Msg)); //向伺服器傳送請求 } // 檔案傳輸過程 void convey_chose(int socketfd) { msg.cmd = 9007; strcpy (msg.toname, msg.fromname); strcpy (msg.fromname, myName); printf ("\n\t當前目錄下的檔案有: \n\n\t"); fflush(stdout); system ("ls"); printf ("\n\t請輸入您要傳送的檔名: "); printf ("\n\t"); scanf ("%s",msg.filename); getchar(); // 開啟要讀的檔案 int fd1 = open(msg.filename, O_RDONLY); if (fd1 == -1) { perror ("open fd1"); return; } int ret = 0; flag1 = 1; // 關閉執行緒 while (ret = read (fd1, msg.msg, 1023)) { if (ret == -1) { perror("read"); break; } printf ("\n\t正在傳輸檔案,請稍候......\n"); write (socketfd, &msg, sizeof(struct Msg)); sleep(1); } msg.cmd = 9008; write (socketfd, &msg, sizeof(struct Msg)); printf ("\n\t檔案傳輸完成\n"); close (fd1); // 重新開啟一個執行緒 pthread_t id; pthread_create(&id, NULL, readMsg, (void*)socketfd); pthread_detach(id); // getchar(); } // 檔案傳輸介面 void convey(int socketfd) { system("clear"); printf ("\t*************************** 網路聊天室 *****************************\n\n\n"); printf ("\t 1、傳輸物件確認\n"); printf ("\t 2、選擇檔案\n"); printf ("\n\t***** 請選擇: "); char ch[2]; fgets(ch, 2, stdin); while (getchar()!= '\n'); switch (ch[0]) { case '1': // 確認傳輸物件 convey_confirm(socketfd); break; case '2': // 檔案選擇 convey_chose(socketfd); break; } printf ("\n\t回車鍵返回 "); 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請稍候.....\n"); usleep(700000); return; } printf ("\t請輸入舊密碼: "); scanf ("%s", msg.msg); getchar(); printf ("\t請輸入新密碼: "); scanf ("%s", msg.filename); getchar(); strcpy (msg.fromname, myName); write (socketfd, &msg, sizeof(struct Msg)); // 向伺服器傳送註冊資訊 printf ("\n\t正在校驗資料,請稍候......\n"); sleep(1); } // 線上登出 void delete_user(int socketfd) { msg.cmd = 8; printf ("\n\t正在處理登出操作......\n"); write (socketfd, &msg, sizeof(struct Msg)); //向伺服器傳送請求 sleep(1); printf ("\t登出完成!\n"); } // 普通使用者操作 void user_do (int socketfd) { char ch[2]; while(1) { interface2(); if (flag3 == 1) { printf ("\n\n\t%s 請求傳輸檔案,是否接收?(y/n):", msg.fromname); fflush(stdout); fgets(ch, 2, stdin); while (getchar()!= '\n'); if (ch[0] != 'y') { printf ("\n\t您已拒絕接受檔案傳輸\n"); printf ("\n\t回車鍵返回 \n"); } else { printf ("\n\t您已接受檔案傳輸請求\n"); printf ("\n\t回車鍵返回 \n"); flag2 = 1; } if (flag2 == 0) { msg.cmd = 9005; // 不接受檔案 strcpy (msg.toname,msg.fromname); // 修改訊號傳送物件 strcpy (msg.fromname, myName); write (socketfd, &msg, sizeof(struct Msg)); } else if (flag2 == 1) { msg.cmd = 9006; // 接受檔案 strcpy (msg.toname,msg.fromname); // 修改訊號傳送物件 strcpy (msg.fromname, myName); write (socketfd, &msg, sizeof(struct Msg)); } flag3 = 0; // 重置是否存在檔案接收請求的判斷 flag2 = 0; } fgets(ch, 2, stdin); while (getchar()!= '\n'); switch(ch[0]) { case '1': // 檢視當前線上人數 display(socketfd); break; case '2': // 進入群聊介面 chat1(socketfd); printf ("\n\t回車鍵返回 \n"); getchar(); break; case '3': // 進入私聊介面 chat2(socketfd); printf ("\n\t回車鍵返回 \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是否確認登出?(y/n): "); fgets(ch, 2, stdin); while (getchar()!= '\n'); if (ch[0] != 'y') { printf ("\n\t請稍候.....\n"); usleep(700000); break; } delete_user(socketfd); case 'q': // 退出聊天室 返回登入介面 flag1 = 1; quit_chatroom(socketfd); printf ("\n\t正在退出,請稍候......\n"); break; } if (flag1 == 1) // 判斷退出條件 { break; } system("clear"); } } // 將成員禁言 void silent (int socketfd) { msg.cmd = 9011; strcpy (msg.fromname, myName); printf ("\n\t請輸入您要禁言的使用者:\n\t"); scanf ("%s",msg.toname); getchar(); write (socketfd, &msg, sizeof(struct Msg)); //向伺服器傳送請求 printf ("\n\t操作完成,請稍候.....\n"); usleep (500000); } // 將成員解除禁言 void silent_del (int socketfd) { msg.cmd = 9012; strcpy (msg.fromname, myName); printf ("\n\t請輸入您要解除禁言的使用者:\n\t"); scanf ("%s",msg.toname); getchar(); write (socketfd, &msg, sizeof(struct Msg)); //向伺服器傳送請求 printf ("\n\t操作完成,請稍候.....\n"); usleep (500000); } // 將成員踢出聊天室 void kickout (int socketfd) { msg.cmd = 9013; strcpy (msg.fromname, myName); printf ("\n\t請輸入您要踢出的使用者:\n\t"); scanf ("%s",msg.toname); getchar(); write (socketfd, &msg, sizeof(struct Msg)); //向伺服器傳送請求 printf ("\n\t操作完成,請稍候.....\n"); usleep (500000); } // 管理員許可權 void supuser (int socketfd) { system("clear"); printf ("\t*************************** 網路聊天室 *****************************\n\n\n"); printf ("\t 1、將成員禁言\n"); printf ("\t 2、將成員解除禁言\n"); printf ("\t 3、將成員踢出聊天室\n"); printf ("\n\t***** 請選擇: "); 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回車鍵返回 "); getchar(); } // 管理員操作 void supuser_do (int socketfd) { char ch[2]; while(1) { interface3(); if (flag3 == 1) { printf ("\n\n\t%s 請求傳輸檔案,是否接收?(y/n):", msg.fromname); fflush(stdout); fgets(ch, 2, stdin); while (getchar()!= '\n'); if (ch[0] != 'y') { printf ("\n\t您已拒絕接受檔案傳輸\n"); printf ("\n\t回車鍵返回 \n"); } else { printf ("\n\t您已接受檔案傳輸請求\n"); printf ("\n\t回車鍵返回 \n"); flag2 = 1; } if (flag2 == 0) { msg.cmd = 9005; // 不接受檔案 strcpy (msg.toname,msg.fromname); // 修改訊號傳送物件 strcpy (msg.fromname, myName); write (socketfd, &msg, sizeof(struct Msg)); } else if (flag2 == 1) { msg.cmd = 9006; // 接受檔案 strcpy (msg.toname,msg.fromname); // 修改訊號傳送物件 strcpy (msg.fromname, myName); write (socketfd, &msg, sizeof(struct Msg)); } flag3 = 0; // 重置是否存在檔案接收請求的判斷 flag2 = 0; } fgets(ch, 2, stdin); while (getchar()!= '\n'); switch(ch[0]) { case '1': // 檢視當前線上人數 display(socketfd); break; case '2': // 進入群聊介面 chat1(socketfd); printf ("\n\t回車鍵返回 \n"); getchar(); break; case '3': // 進入私聊介面 chat2(socketfd); printf ("\n\t回車鍵返回 \n"); getchar(); break; case '4': // 檢視聊天記錄 dis_histroy(socketfd); getchar(); break; case '5': // 檔案傳輸 convey(socketfd); break; case '6': // 更改密碼 change_pass(socketfd); break; case '8': // 管理員許可權操作 supuser (socketfd); break; case '7': // 線上登出 printf ("\n\t是否確認登出?(y/n): "); fgets(ch, 2, stdin); while (getchar()!= '\n'); if (ch[0] != 'y') { printf ("\n\t請稍候.....\n"); usleep(700000); break; } delete_user(socketfd); case 'q': // 退出聊天室 返回登入介面 flag1 = 1; quit_chatroom(socketfd); printf ("\n\t正在退出,請稍候......\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請輸入使用者名稱: "); scanf ("%s", myName); getchar(); printf ("\t請輸入密碼: "); scanf ("%s", password); getchar(); strcpy (msg.fromname, myName); strcpy (msg.msg, password); write (socketfd, &msg, sizeof(struct Msg)); // 向伺服器傳送登入請求 read (socketfd, &msg, sizeof(struct Msg)); // 讀取伺服器的登入迴應 printf ("\n\t正在校驗資料......\n"); sleep(1); if (msg.cmd == 1002) { printf ("\n\t驗證通過,正在登入......\n"); usleep(1500000); flag4 = msg.sig; // 更新禁言狀態 // 執行緒分離,用來監聽伺服器返回資訊 pthread_t id; pthread_create(&id, NULL, readMsg, (void*)socketfd); pthread_detach(id); user_do (socketfd); } else if (msg.cmd == 1003) { printf ("\n\t驗證通過,正在登入......\n"); usleep(1500000); // 執行緒分離,用來監聽伺服器返回資訊 pthread_t id; pthread_create(&id, NULL, readMsg, (void*)socketfd); pthread_detach(id); supuser_do (socketfd); } else if (msg.cmd == -4) { printf ("\n\t此賬號已在別處登入\n"); } else if (msg.cmd == -3) { printf ("\n\t驗證失敗,請您確認資訊後重新登入\n"); } else if (msg.cmd == -2) { printf ("\t驗證失敗,資料庫開啟失敗\n"); } else if (msg.cmd == -1) { printf ("\t資料庫操作失敗\n"); } usleep(1500000); } // 註冊(可註冊管理員) void reg(int socketfd) { msg.cmd = 1; printf ("\t使用者註冊:\n"); printf ("\t請輸入使用者名稱: "); scanf ("%s", myName); getchar(); printf ("\t請輸入密碼: "); scanf ("%s", msg.msg); getchar(); printf ("\t管理員: "); scanf ("%d", &msg.sig); getchar(); strcpy (msg.fromname, myName); write (socketfd, &msg, sizeof(struct Msg)); // 向伺服器傳送註冊資訊 read (socketfd, &msg, sizeof(struct Msg)); // 讀取伺服器的註冊迴應 printf ("\n\t正在校驗資料......\n"); sleep(1); if (msg.cmd == 1001) { printf ("\n\t註冊成功!\n\t請稍候......\n"); } else if (msg.cmd == -1) { printf ("\t註冊失敗,該使用者名稱已被註冊\n"); } else if (msg.cmd == -2) { printf ("\t註冊失敗,資料庫開啟失敗\n"); } usleep(1500000); } // 向伺服器傳送請求 void ask_server(int socketfd) { char ch[2]; while (1) { interface1(); fgets(ch, 2, stdin); while (getchar()!= '\n'); switch(ch[0]) { case '1': // 註冊 reg(socketfd); break; case '2': // 登入 log_in(socketfd); break; case 'q': // 退出 exit(1); } system("clear"); } } int main(int argc, char **argv) { // 開啟資料庫Histroy.db int ret = sqlite3_open("Histroy.db", &database); if (ret != SQLITE_OK) { printf ("開啟資料庫失敗\n"); return -1; } // 建立 histroy