Tcp、select函数实现在线词典(C语言)
生活随笔
收集整理的這篇文章主要介紹了
Tcp、select函数实现在线词典(C语言)
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
功能:
注冊(cè):添加用戶名和密碼到數(shù)據(jù)庫(kù)。
登錄:檢索數(shù)據(jù)庫(kù),查詢是否符合。
查詢:檢索字典文本文件,查詢結(jié)果存入數(shù)據(jù)庫(kù)中。
歷史:檢索數(shù)據(jù)庫(kù),將登錄賬戶的查詢歷史打印。
TCP服務(wù)器:
聲明與定義
#define ERRLOG(msg) \do \{ \printf("%s %s(%d):", __FILE__, __func__, __LINE__); \perror(msg); \exit(-1); \} while (0) //消息結(jié)構(gòu)體封裝 typedef struct msg {char code;char name[20];char txt[128]; } msg_t;sqlite3 *sql_init();//數(shù)據(jù)庫(kù)初始化 int log_sql(msg_t *clientmsg, sqlite3 *my_sql, int clientfd);//注冊(cè) int select_sql(msg_t *clientmsg, sqlite3 *my_sql, int clientfd);//登錄 int printf_sql(msg_t *clientmsg, sqlite3 *my_sql, int clientfd);//檢索單詞 int history_sql(msg_t *clientmsg, sqlite3 *my_sql, int clientfd);//查看歷史 int str_deal(char *buf);//字符串處理 int time_get(char *timestr);//獲取時(shí)間主函數(shù)體
//檢查輸入if (3 != argc){printf("Usage: %s <IP> <port>\n", argv[0]);return -1;} 1、第一步配置服務(wù)器結(jié)構(gòu)體和套接字 //套接字int sockfd = socket(AF_INET, SOCK_STREAM, 0);if (-1 == sockfd){ERRLOG("socket error");} //配置服務(wù)器結(jié)構(gòu)體struct sockaddr_in serveraddr;memset(&serveraddr, 0, sizeof(serveraddr));serveraddr.sin_family = AF_INET;serveraddr.sin_port = htons(atoi(argv[2]));serveraddr.sin_addr.s_addr = inet_addr(argv[1]);socklen_t serveraddr_len = sizeof(serveraddr);if (-1 == bind(sockfd, (struct sockaddr *)&serveraddr, serveraddr_len)){ERRLOG("bind error");}if (-1 == listen(sockfd, 5)){ERRLOG("listen error");} 2、配置select函數(shù)的文件句柄 int maxfd = 0;fd_set readfds;fd_set readfdstemp;FD_ZERO(&readfds);FD_ZERO(&readfdstemp);//將套接字描述符添加到句柄中FD_SET(sockfd, &readfds);maxfd = maxfd > sockfd ? maxfd : sockfd; 3、初始化數(shù)據(jù)庫(kù) sqlite3 *my_sql = sql_init(); 4、通過(guò)select函數(shù)檢索句柄實(shí)現(xiàn)的邏輯結(jié)構(gòu) int ret = 0;//保存有幾個(gè)文件描述符就緒int i = 0;//在循環(huán)中代表了文件描述符int clientfd;//客戶端連接創(chuàng)建的套接字int nbyte = 0;//接受多少字節(jié)while (1){FD_ZERO(&readfdstemp);readfdstemp = readfds;//阻塞等待有1個(gè)或者多個(gè)文件描述符就緒ret = select(maxfd + 1, &readfdstemp, NULL, NULL, NULL);if (ret == -1){PRINT_ERR("select init error");}else{//遍歷句柄,區(qū)分有客戶端連接還是客戶端發(fā)送消息for (i = 3; i < (maxfd + 1) && ret != 0; i++){if (FD_ISSET(i, &readfdstemp)){if (i == sockfd){if ((clientfd = accept(i, NULL, NULL)) == -1){PRINT_ERR("accept error");}printf("新用戶已連接\n");FD_SET(clientfd, &readfds);maxfd = maxfd > clientfd ? maxfd : clientfd;}else{memset(&severmsg, 0, sizeof(severmsg));if ((nbyte = recv(i, &severmsg, sizeof(severmsg), 0)) == -1){PRINT_ERR("recv error");}else if (nbyte == 0){printf("用戶斷開(kāi)連接\n");FD_CLR(i, &readfds);close(i);continue;}//根據(jù)結(jié)構(gòu)體中的操作碼.code判斷客戶端需求switch (severmsg.code){case '1':log_sql(&severmsg, my_sql, i);break;case '2':select_sql(&severmsg, my_sql, i);break;case '3':printf_sql(&severmsg, my_sql, i);break;case '4':history_sql(&severmsg, my_sql, i);break;}}//每次處理完一個(gè)就緒,已就緒的文件描述符就減少了一個(gè)ret--;}}}}功能模塊
數(shù)據(jù)庫(kù)初始化:
客戶端
聲明與定義
#define ERRLOG(msg) \do \{ \printf("%s %s(%d):", __FILE__, __func__, __LINE__); \perror(msg); \exit(-1); \} while (0)typedef struct msg {char code;char name[20];char txt[128]; } msg_t;int log_sql(msg_t *clientmsg, int sockfd); int select_sql(msg_t *clientmsg, int sockfd); int printf_sql(msg_t *clientmsg, int sockfd); int history_sql(msg_t *clientmsg, int sockfd);主函數(shù)體
if (3 != argc){printf("Usage: %s <IP> <port>\n", argv[0]);return -1;} 1、配置服務(wù)器和服務(wù)器結(jié)構(gòu)體、連接服務(wù)器 int sockfd = socket(AF_INET, SOCK_STREAM, 0);if (-1 == sockfd){ERRLOG("socket error");}struct sockaddr_in serveraddr;memset(&serveraddr, 0, sizeof(serveraddr));serveraddr.sin_family = AF_INET;serveraddr.sin_port = htons(atoi(argv[2]));serveraddr.sin_addr.s_addr = inet_addr(argv[1]);socklen_t serveraddr_len = sizeof(serveraddr);if (-1 == connect(sockfd, (struct sockaddr *)&serveraddr, serveraddr_len)){ERRLOG("connect error");} 2、邏輯及實(shí)現(xiàn) msg_t clientmsg;memset(&clientmsg, 0, sizeof(clientmsg));while (1){printf("************************************************\n");printf("**************1、注冊(cè) 2、登錄 *******************\n");printf("************************************************\n");scanf(" %c", &(clientmsg.code));printf("請(qǐng)輸入用戶名和密碼:");scanf("%s %s", clientmsg.name, clientmsg.txt);switch (clientmsg.code){case '1':log_sql(&clientmsg, sockfd);break;case '2':select_sql(&clientmsg, sockfd);if (clientmsg.code == '2'){ //如果登陸失敗,服務(wù)器傳回錯(cuò)誤碼5goto NEXT;}break;}memset(clientmsg.txt, 0, sizeof(clientmsg.txt));clientmsg.code = 0;} NEXT:while (1){printf("************************************************\n");printf("**********1、查詢 2、歷史 3、登出***************\n");printf("************************************************\n");scanf(" %c", &(clientmsg.code));switch (clientmsg.code){case '1':clientmsg.code = '3';printf("輸入單詞:");scanf("%s", clientmsg.txt);printf_sql(&clientmsg, sockfd);break;case '2':clientmsg.code = '4';history_sql(&clientmsg, sockfd);break;}memset(clientmsg.txt, 0, sizeof(clientmsg.txt));clientmsg.code = 0;}功能模塊
1、注冊(cè)模塊 int log_sql(msg_t *clientmsg, int sockfd) {int nbyte = 0;if (send(sockfd, clientmsg, sizeof(msg_t), 0) == -1){PRINT_ERR("send error");}if ((nbyte = recv(sockfd, clientmsg, sizeof(msg_t), 0)) == -1){PRINT_ERR("recv error");}if (clientmsg->code == '5'){printf("注冊(cè)成功\n");}else{printf("用戶名已被注冊(cè)\n");}return 0; } 2、登錄 int select_sql(msg_t *clientmsg, int sockfd) {int nbyte = 0;if (send(sockfd, clientmsg, sizeof(msg_t), 0) == -1){PRINT_ERR("send error");}if ((nbyte = recv(sockfd, clientmsg, sizeof(msg_t), 0)) == -1){PRINT_ERR("recv error");}if (clientmsg->code == '5'){printf("用戶名或密碼不正確,請(qǐng)確認(rèn)用戶名和密碼或注冊(cè)\n");}else{printf("登錄成功\n");}return 0; } 3、查詢 int printf_sql(msg_t *clientmsg, int sockfd) {int nbyte = 0;if (send(sockfd, clientmsg, sizeof(msg_t), 0) == -1){PRINT_ERR("send error");}if ((nbyte = recv(sockfd, clientmsg, sizeof(msg_t), 0)) == -1){PRINT_ERR("recv error");}printf("%s\n", clientmsg->txt);return 0; } 4、歷史查看 int history_sql(msg_t *clientmsg, int sockfd) {int nbyte = 0;if (send(sockfd, clientmsg, sizeof(msg_t), 0) == -1){PRINT_ERR("send error");}//判斷是否接收完畢while (strcmp(clientmsg->txt,"**over**")){if ((nbyte = recv(sockfd, clientmsg, sizeof(msg_t), 0)) == -1){PRINT_ERR("recv error");}printf("%s\n", clientmsg->txt);}return 0; }總結(jié)
以上是生活随笔為你收集整理的Tcp、select函数实现在线词典(C语言)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: php实现国外邮箱,发送电子邮件 · 国
- 下一篇: Plotly中绘制三种经典的股票交易图表