项目要求:

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

  2. 单词查询功能

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

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

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

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

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

格式要求:

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

  2. 功能代码封装成函数

思路

1.服务器通过多进程的方式,可同时处理多个客户端

2.服务器运行之前先检查数据库是否有单词列表,没有就需要将txt文件中的单词列表导入到数据库中,同时也要创建保存用户名和密码的数据库。

3.客户端登录验证密码、用户名是否正确,返回F,登录失败。登录成功返回D,将user数据库中的user表中的online修改为Y,防止重复登录。

4.客户端请求注册,验证用户名是否重复,不重复注册成功,新建一个表保存历史记录

5.客户端请求查词,查找成功返回单词的意思,查找失败就返回F,记录查词成功记录到数据库中

6.客户端请求查看历史记录,将以用户名存储的表中数据,发送给客户端

7.客户端退出将进程退出,回收资源,将user数据库中的user表中的line修改为N

8.客户端发送登录、注册、查词、查看历史记录的信息给服务器,接收服务器的信息,一般返回的head为F是失败

服务器代码

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <string.h>
#include <sqlite3.h>
#include <signal.h>
#include <time.h>
#define PORT 8888
#define IP  "192.168.1.9"
//打印错误新的宏函数
#define ERR_MSG(msg)  do{\fprintf(stderr, "__%d__", __LINE__);\perror(msg);\
}while(0)
//发送接收结构体
struct message
{char head;char msg[128];char name[50];
};
typedef void (*sighandler_t)(int);
void handler(int sig);
void word_exist();
int tcp_con();
int rcv_cli_msg(int newfd, struct sockaddr_in cin);
int sign_up(int newfd,struct sockaddr_in cin,char *msg,sqlite3* db_user);
int sign_in(int newfd,struct sockaddr_in cin,char *msg,sqlite3* db_user);
int search(int newfd,struct sockaddr_in cin,struct message cil_buf,sqlite3* db_word,sqlite3* db_user);
int history(int newfd,struct sockaddr_in cin,struct message cil_buf,sqlite3* db_user);
int do_select(sqlite3* db,char* table,char* name,char* buf);
int do_insert(sqlite3* db,char* buf);
int word_into();
int isonline(char* msg,sqlite3* db_user);
int log_out(char* name,sqlite3* db_user);int main(int argc, const char *argv[])
{//捕获17号信号 SIGCHLDsighandler_t s = signal(17, handler);if(SIG_ERR == s){ERR_MSG("signal");return -1;}//检查是否有单词数据库,创建用户数据库word_exist();printf("初始化完成\n");//TCP连接int sfd = tcp_con();//等待客户端连接printf("等待客户端连接\n");int newfd = 0;pid_t pid = 0;struct sockaddr_in cin;socklen_t addrlen = sizeof(cin);while(1){//父进程只负责连接newfd = accept(sfd, (struct sockaddr*)&cin, &addrlen);if(newfd < 0){ERR_MSG("accept");return -1;}printf("[%s : %d] newfd = %d 连接成功\n", inet_ntoa(cin.sin_addr), ntohs(cin.sin_port),newfd);//创建子进程pid = fork();if(pid > 0){close(newfd);}else if(0 == pid){close(sfd);rcv_cli_msg(newfd,cin);close(newfd);exit(0);}else{ERR_MSG("fork");return -1;}}close(sfd);return 0;
}
void handler(int sig)
{//回收僵尸进程while(waitpid(-1, NULL, WNOHANG) > 0);
}
//初始化判断
void word_exist()
{//导入单词到数据库if(access("./word.db",F_OK) ==  0){printf("单词数据库已存在\n");}else{if(access("./dict.txt",F_OK) == -1){printf("存储单词的文本不存在\n");exit(0);}else{printf("正在导入单词\n");word_into();printf("单词数据库导入成功\n");}}//创建用户数据库if(access("./user.db",F_OK) == 0)//数据库已经存在{return;}//打开数据库printf("正在创建用户数据库\n");sqlite3* db_user = NULL;if(sqlite3_open("./user.db", &db_user) != SQLITE_OK){printf("errmsg:%s\n", sqlite3_errmsg(db_user));fprintf(stderr, "__%d__ sqlite3_open failed\n", __LINE__);exit(0);}//创建一个用户表格char* sql = "create table if not exists user (name char primary key, password char,online char);" ;char* errmsg = NULL;if(sqlite3_exec(db_user, sql, NULL, NULL, &errmsg) != SQLITE_OK){fprintf(stderr, "__%d__ sqlite3_exec:%s\n", __LINE__, errmsg);exit(0);}//关闭数据库sqlite3_close(db_user);printf("用户数据库创建成功\n");return;
}
int word_into()
{char buf[100];//打开文件FILE*fd = fopen("./dict.txt","r");if(NULL == fd){perror("fopen");return -1;}//打开数据库sqlite3* db_word = NULL;if(sqlite3_open("./word.db",&db_word) != SQLITE_OK){printf("errmsg:%s\n",sqlite3_errmsg(db_word));fprintf(stderr,"__%d__ sqlite3_open failed\n",__LINE__);return -1;}//创建一个表格char sql[128] = "create table if not exists word (word char,mean char)";char* errmsg = NULL;if(sqlite3_exec(db_word,sql,NULL,NULL,&errmsg) != SQLITE_OK){fprintf(stderr,"__%d__ sqlite3_exec:%s\n",__LINE__,errmsg);return -1;}//读取文件内容存储到表格中while(1){if(NULL == fgets(buf,sizeof(buf),fd))//获取一行的内容break;do_insert(db_word,buf);}sqlite3_close(db_word);fclose(fd);return 0;
}
//将单词插入到数据库中
int do_insert(sqlite3* db,char* buf)
{char word[50] = "",mean[50] = "";char* q = buf;int num = 0;char* errmsg = NULL;char sql[128] = "";//获取一行中的单词,遇到二个空格单个单词结束while(1){if(*q == ' ' && *(q+1) == ' '){while(1){if(*q != ' ')//将q指向下个不是空格的位置,即词性的开头break;q++;}break;}word[num] = *q;num++;q++;}//q指向后面内容就是单词词性和中文,直接拷贝到mean字符串中q[strlen(q)-1] = 0;strcpy(mean,q);sprintf(sql,"insert into word values(\"%s\",\"%s\")",word,mean);//存入到表中if(sqlite3_exec(db,sql,NULL,NULL,&errmsg) != SQLITE_OK){fprintf(stderr,"__%d__ sqlite3_exec:%s\n",__LINE__,errmsg);return -1;}return 0;
}
//TCP连接
int tcp_con()
{int sfd = socket(AF_INET,SOCK_STREAM,0);if(sfd < 0){ERR_MSG("socket");exit(0);}//允许端口快速重用int reuse = 1;if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0){ERR_MSG("setsockopt");exit(0);}//填充地址信息结构体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){ERR_MSG("bind");exit(0);}//将套接字设置为被动监听状态,让内核去监听是否有客户端连接;if(listen(sfd, 10) < 0){ERR_MSG("listen");exit(0);}//打开数据库sqlite3* db_user = NULL;if(sqlite3_open("./user.db",&db_user) != SQLITE_OK){printf("errmsg:%s\n",sqlite3_errmsg(db_user));fprintf(stderr,"__%d__ sqlite3_open failed\n",__LINE__);return -1;}//修改所有用户为非在线状态char sql[128] = "update user set online=\"N\"";char* errmsg = NULL;if(sqlite3_exec(db_user, sql, NULL, NULL, &errmsg) != SQLITE_OK){fprintf(stderr, "__%d__ sqlite3_exec:%s\n", __LINE__, errmsg);return -1;}//关闭数据库sqlite3_close(db_user);return sfd;}
//接收客户端信息
int rcv_cli_msg(int newfd, struct sockaddr_in cin)
{       //打开存储用户信息的数据库sqlite3* db_user = NULL;if(sqlite3_open("./user.db",&db_user) != SQLITE_OK){printf("errmsg:%s\n",sqlite3_errmsg(db_user));fprintf(stderr,"__%d__ sqlite3_open failed\n",__LINE__);return -1;}     //打开存储单词的数据库sqlite3* db_word = NULL;if(sqlite3_open("./word.db",&db_word) != SQLITE_OK){printf("errmsg:%s\n",sqlite3_errmsg(db_word));fprintf(stderr,"__%d__ sqlite3_open failed\n",__LINE__);return -1;}struct message buf;ssize_t res = 0;char name[50] = "";while(1){memset(&buf,0, sizeof(buf));//循环接收 res = recv(newfd, &buf, sizeof(buf), 0);if(res < 0){ERR_MSG("recv");return -1;}else if(0 == res){printf("[%s : %d] newfd = %d 断开连接\n", inet_ntoa(cin.sin_addr), ntohs(cin.sin_port),newfd);//修改用户为非在线状态char sql[128] = "";sprintf(sql, "update user set online=\"N\" where name=\"%s\";", name);char* errmsg = NULL;if(sqlite3_exec(db_user, sql, NULL, NULL, &errmsg) != SQLITE_OK){fprintf(stderr, "__%d__ sqlite3_exec:%s\n", __LINE__, errmsg);return -1;}//关闭数据库sqlite3_close(db_user);sqlite3_close(db_word);return 0;}switch (buf.head){case 'Z'://用户注册sign_up(newfd,cin,buf.msg,db_user);break;case 'D'://用户登录sign_in(newfd,cin,buf.msg,db_user);strcpy(name,buf.msg);break;case 'C'://查询单词search(newfd,cin,buf,db_word,db_user);break;case 'H'://查历史记录history(newfd,cin,buf,db_user);break;case 'Q'://退出登录log_out(name,db_user);break;default:printf("buf.head = %c \t客户端错误\n",buf.head);}}return 0;
}
//用户注册
int sign_up(int newfd,struct sockaddr_in cin,char *msg,sqlite3* db_user)
{printf("用户请求注册\n");struct message buf;buf.head = 'Z';strcpy(buf.msg,"注册成功\n");char sql[128] = "";sprintf(sql, "insert into user values(\"%s\", \"%s\",\"%s\");",msg,(msg+strlen(msg)+1),"N");char* errmsg = NULL;if(sqlite3_exec(db_user, sql, NULL, NULL, &errmsg) != SQLITE_OK){if(sqlite3_errcode(db_user) == 19){printf("用户名[%s]重复注册\n",msg);//重复注册buf.head = 'F';strcpy(buf.msg,"用户名重复\n");//发送给客户端if(send(newfd,&buf,sizeof(buf),0) < 0){ERR_MSG("send");return -1;}return -1;}fprintf(stderr, "__%d__ sqlite3_exec:%s\n", __LINE__, errmsg);}//创建一张表存储历史记录sprintf(sql,"create table if not exists %s (word char,mean char,time char);",msg);  if(sqlite3_exec(db_user, sql, NULL, NULL, &errmsg) != SQLITE_OK){fprintf(stderr, "__%d__ sqlite3_exec:%s\n", __LINE__, errmsg);return -1;}printf("用户名[%s]注册成功\n",msg);//发送给客户端if(send(newfd,&buf,sizeof(buf),0) < 0){ERR_MSG("send");return -1;}return 0;
}
//用户登录
int sign_in(int newfd,struct sockaddr_in cin,char *msg,sqlite3* db_user)
{char name[50] = "";char password[50] = "";sprintf(name,"name='%s'",msg);struct message buf;printf("用户请求登录\n");buf.head = 'D';strcpy(buf.msg,"登录成功\n");//查询用户名密码是否正确if(do_select(db_user,"user",name,password) == 0){if(isonline(msg,db_user) != 0){printf("用户名[%s]重复登录\n",msg);buf.head = 'F';strcpy(buf.msg,"重复登录\n");//发送给客户端if(send(newfd,&buf,sizeof(buf),0) < 0){ERR_MSG("send");return -1;}   return 0;}}if(do_select(db_user,"user",name,password) == -1){//用户名错误buf.head = 'F';strcpy(buf.msg,"用户名不存在\n");printf("用户名[%s]不存在\n",msg);}else if(strcmp(password,msg+strlen(msg)+1) != 0){//密码错误buf.head = 'F';strcpy(buf.msg,"密码错误\n");printf("用户名[%s]密码错误\n",msg);}else{printf("用户名[%s]登录成功\n",msg);//修改用户为在线状态char sql[128] = "";sprintf(sql, "update user set online=\"Y\" where name=\"%s\";", msg);char* errmsg = NULL;if(sqlite3_exec(db_user, sql, NULL, NULL, &errmsg) != SQLITE_OK){fprintf(stderr, "__%d__ sqlite3_exec:%s\n", __LINE__, errmsg);return -1;}}//发送给客户端if(send(newfd,&buf,sizeof(buf),0) < 0){ERR_MSG("send");return -1;}
}
//判断用户是否在线
int isonline(char* msg,sqlite3* db_user)
{//判断是否在线,N不在线,Y在线char sql[128] = "";char ** pres = NULL;    //存储查询结果的首地址int row, column;        //查询结果的行列数char* errmsg = NULL;sprintf(sql,"select * from user where name=\"%s\"",msg);if(sqlite3_get_table(db_user, sql, &pres, &row, &column, &errmsg) != SQLITE_OK){fprintf(stderr, "__%d__ sqlite3_get_table:%s\n", __LINE__, errmsg);return -1;}//能运行到当前位置则说明,查询函数运行成功if(strcmp(pres[5],"Y") == 0){//释放获取到的空间sqlite3_free_table(pres);pres = NULL;return -1;}//释放获取到的空间sqlite3_free_table(pres);pres = NULL;return 0;    }//查询数据库的单词意思和用户名
int do_select(sqlite3* db,char* table,char* name,char* buf)
{char sql[128] = "";char ** pres = NULL;    //存储查询结果的首地址int row, column;        //查询结果的行列数char* errmsg = NULL;sprintf(sql,"select * from %s where %s;",table,name);if(sqlite3_get_table(db, sql, &pres, &row, &column, &errmsg) != SQLITE_OK){fprintf(stderr, "__%d__ sqlite3_get_table:%s\n", __LINE__, errmsg);return -1;}if(column == 0)//没有相关的单词或者用户名{printf("没有查询到\n");return -1;}strcpy(buf,pres[column+1]);//释放获取到的空间sqlite3_free_table(pres);pres = NULL;return 0;
}
//用户请求查词
int search(int newfd,struct sockaddr_in cin,struct message cil_buf,sqlite3* db_word,sqlite3* db_user)
{printf("用户[%s]请求查词\n",cil_buf.name);struct message buf;buf.head = 'C';//将单词和意思保存char word[150] = "";char mean[150] = "";sprintf(word,"word='%s'",cil_buf.msg);//调用查找函数查找单词if(do_select(db_word,"word",word,mean) == -1){//单词不存在buf.head = 'F';strcpy(buf.msg,"单词不存在\n");printf("单词[%s]不存在\n",cil_buf.msg);}else{printf("单词[%s]查询成功,解释[%s]\n",cil_buf.msg,mean);strcpy(buf.msg,mean);}//发送给客户端if(send(newfd,&buf,sizeof(buf),0) < 0){ERR_MSG("send");return -1;}//存储单词查询的记录if(buf.head == 'C'){char ti[30] = "";time_t t = time(NULL);struct tm *info = NULL;info = localtime(&t);//拼接时间sprintf(ti,"%d-%02d-%02d %02d:%02d:%02d",info->tm_year+1900, info->tm_mon+1, info->tm_mday,info->tm_hour, info->tm_min, info->tm_sec);char sql[256] = "";sprintf(sql, "insert into %s values(\"%s\", \"%s\",\" %s\");",cil_buf.name,cil_buf.msg,mean,ti);char* errmsg = NULL;if(sqlite3_exec(db_user, sql, NULL, NULL, &errmsg) != SQLITE_OK){fprintf(stderr, "__%d__ sqlite3_exec:%s\n", __LINE__, errmsg);return -1;}printf("查词[%s]记录存储成功\n",cil_buf.msg);}
}
//查询历史记录
int history(int newfd,struct sockaddr_in cin,struct message cil_buf,sqlite3* db_user)
{printf("用户[%s]请求查词历史记录\n",cil_buf.name);struct message buf;char his[128] = "";buf.head = 'H';//查找数据的内容char sql[128] = "select *  from stu";char ** pres = NULL;    //存储查询结果的首地址int row, column;        //查询结果的行列数char* errmsg = NULL;sprintf(sql,"select * from %s",cil_buf.name);if(sqlite3_get_table(db_user, sql, &pres, &row, &column, &errmsg) != SQLITE_OK){fprintf(stderr, "__%d__ sqlite3_get_table:%s\n", __LINE__, errmsg);return -1;}//能运行到当前位置则说明,查询函数运行成功int i = 0;ssize_t res;for(i=0; i<(row+1)*column; i++){strcat(his,pres[i]);strcat(his,"|");if(i%column == (column-1)){strcpy(buf.msg,his);if(send(newfd,&buf,sizeof(buf),0) < 0){ERR_MSG("send");return -1;}bzero(his,sizeof(his));res = recv(newfd,&buf,sizeof(buf),0);if(res < 0){ERR_MSG("recv");return -1;}else if(res == 0){printf("客户端退出\n");return 0;}if(buf.head != 'H'){printf("客户端异常\n");return -1;}}}buf.head = 'F';if(send(newfd,&buf,sizeof(buf),0) < 0){ERR_MSG("send");return -1;}//释放获取到的空间sqlite3_free_table(pres);pres = NULL;return 0;
}
//退出登录,修改数据库信息为N
int log_out(char* name,sqlite3* db_user)
{printf("用户[%s]退出登录\n",name);//修改用户为非在线状态char sql[128] = "";sprintf(sql, "update user set online=\"N\" where name=\"%s\";",name);char* errmsg = NULL;if(sqlite3_exec(db_user, sql, NULL, NULL, &errmsg) != SQLITE_OK){fprintf(stderr, "__%d__ sqlite3_exec:%s\n", __LINE__, errmsg);return -1;}return 0;
}

 客户端代码

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <string.h>//打印错误新的宏函数
#define ERR_MSG(msg)  do{\fprintf(stderr, " __%d__ ", __LINE__);\perror(msg);\
}while(0)
//发送接收结构体
struct message
{char head;char msg[128];char name[50];
};//指定要连接的服务器的地址信息
#define PORT 8888
#define IP  "192.168.1.9"void menu(int n);
int sign_up(int sfd);
int sign_in(int sfd);
int word(int sfd,char* user);
int history(int sfd,char* user);
int cil_search(int sfd,char* user);
int log_out(int sfd,char* user);int main(int argc, const char *argv[])
{//创建流式套接字int sfd = socket(AF_INET, SOCK_STREAM, 0);if(sfd < 0){ERR_MSG("socket");return -1;}//填充要连接的服务器的地址信息结构体struct sockaddr_in sin;sin.sin_family         = AF_INET;sin.sin_port         = htons(PORT);sin.sin_addr.s_addr = inet_addr(IP);//连接服务器 connectif(connect(sfd, (struct sockaddr*)&sin, sizeof(sin)) < 0){ERR_MSG("connect");return -1;}    printf("连接服务器成功\n");struct message buf;int choose;int num;while(1){menu(1);scanf("%d",&choose);while(getchar() != 10);switch(choose){case 1://注册sign_up(sfd);break;case 2://登录num = sign_in(sfd);break;case 3://退出system("clear");exit(0);default:printf("输入错误\n");}}return 0;
}
//菜单函数
void menu(int n)
{if(1 == n){printf("----------------\n");printf("-----1.注册-----\n");printf("-----2.登录-----\n");printf("-----3.退出-----\n");printf("----------------\n");}else if(2 == n){printf("-----------------\n");printf("---1.查单词------\n");printf("---2.历史记录----\n");printf("---3.返回上一级--\n");printf("-----------------\n");}
}
//注册用户
int sign_up(int sfd)
{system("clear");struct message buf;buf.head = 'Z';char user[50] = "";char password[50] = "";printf("请输入要注册的用户名user>>>");scanf("%s",user);printf("请输入密码password>>>");scanf("%s",password);sprintf(buf.msg,"%s%c%s",user,0,password);if(send(sfd,&buf,sizeof(buf),0) <0){ERR_MSG("send");return -1;}if(recv(sfd,&buf,sizeof(buf),0) < 0)//接收服务器的信息{ERR_MSG("recv");return -1;}if(buf.head == 'Z')//'Z'注册成功{printf("%s",buf.msg);printf("您的用户名:%s\n",user);printf("您的密码:%s\n",password);}else if(buf.head == 'F')//'F'没有注册成功{printf("%s",buf.msg);}return 0;
}
//用户登录
int sign_in(int sfd)
{system("clear");struct message buf;buf.head = 'D';char user[50] = "";char password[50] = "";printf("请输入用户名user>>>");scanf("%s",user);printf("请输入密码password>>>");scanf("%s",password);sprintf(buf.msg,"%s%c%s",user,0,password);if(send(sfd,&buf,sizeof(buf),0) <0){ERR_MSG("send");return -1;}if(recv(sfd,&buf,sizeof(buf),0) < 0){ERR_MSG("recv");return -1;}if(buf.head == 'D')//'D'登录成功{printf("%s",buf.msg);}else if(buf.head == 'F')//'F'登录失败{printf("%s",buf.msg);return -1;//密码错误,用户名或者用户已在线不存在}word(sfd,user);//调用查词函数return 0;
}
//查词历史记录
int word(int sfd,char* user)
{int choose;while(1){menu(2);scanf("%d",&choose);while(getchar()!=10);switch(choose){case 1:cil_search(sfd,user);//查词break;case 2:history(sfd,user);//查看历史记录break;case 3:log_out(sfd,user);//回到上一级return 0;default:printf("输入错误\n");}}
}
//查询单词
int cil_search(int sfd,char* user)
{system("clear");struct message buf;char str[128] = "";buf.head = 'C';while(1){strcpy(buf.name,user);buf.head = 'C';printf("请输入单词(输入#结束查词)>>>");fgets(str,sizeof(str),stdin);str[strlen(str)-1] = 0;if(str[0] == '#')//退出查词{system("clear");break;}strcpy(buf.msg,str);if(send(sfd,&buf,sizeof(buf),0) < 0){ERR_MSG("send");return -1;}if(recv(sfd,&buf,sizeof(buf),0) < 0){ERR_MSG("recv");return -1;}if(buf.head == 'F')//F查词失败{printf("单词[%s]%s",str,buf.msg);}else if(buf.head == 'C')//C查词成功{printf("单词:[%s]\t解释:[%s]\n",str,buf.msg);}else{printf("服务器异常");break;}}
}
//历史记录
int history(int sfd,char* user)
{system("clear");int n = 0;struct message buf;char* q = buf.msg;strcpy(buf.name,user);buf.head = 'H';if(send(sfd,&buf,sizeof(buf),0) < 0){ERR_MSG("send");return -1;}while(1){strcpy(buf.name,user);q = buf.msg;if(recv(sfd,&buf,sizeof(buf),0) < 0)//接服务器的信息{ERR_MSG("recv");return -1;}if(buf.head == 'F')//接收完毕{if(n == 1)//n被修改为1,查过词{printf("查询完毕\n");}else printf("你还没有查过词\n");break;}else{while(*q != '\0')//一个一个字符打印{if(*q != '|'){printf("%c",*q);}else{printf("\t\t");//遇到|打印\t}q++;n = 1;}printf("\n");}if(send(sfd,&buf,sizeof(buf),0) < 0)//发送ASK验证{ERR_MSG("send");return -1;}}
}
//退出登录
int log_out(int sfd,char* user)
{struct message buf;strcpy(buf.msg,user);//向服务器发送退出登录信息buf.head = 'Q';if(send(sfd,&buf,sizeof(buf),0) < 0){ERR_MSG("send");return -1;}system("clear");return 0;
}

C语言实现电子词典(网络编程大作业)相关推荐

  1. Unix网络编程---第一次作业

    Unix网络编程---第一次作业   要求: 客户端:从命令行读入服务器的IP地址:并连接到服务器: 服务器端:    接受客户的连接请求,并显示客户的IP地址和端口号. 实现代码: 1.客户端程序: ...

  2. 你所需要的java网络编程大总结

    好好学java java知识分享/学习教程免费分享 关注 精彩内容 你所需要的java全套视频教程 你所需要的java电子图书 你所需要的大数据视频教程 你所需要的java练习项目 如 / 梦 上个月 ...

  3. Linux Linux程序练习十一(网络编程大文件发送UDP版)

    //网络编程发送端--大文件传输(UDP) #include <stdio.h> #include <stdlib.h> #include <string.h> # ...

  4. SCL语言中如何进行网络编程?

    在SCL(Structured Control Language)程序中进行网络编程,需要使用相应的网络通信模块来实现.SCL可用的网络通信模块包括: 1. CP443-1:这是西门子公司推出的以太网 ...

  5. C语言课设车票管理系统(大作业)

    C语言课程设计(大作业)(车票管理系统) 一.项目简介 设计一个车票管理系统实现录入.查看班次信息,售票,退票等基本功能.设计中要求综合运用所学知识,上机解决一些与实际应用结合紧密的.规模较大的问题, ...

  6. Python实训day12am【网络爬虫大作业简略解析:动态生成html页面、数据写入Excel】

    Python实训-15天-博客汇总表 目录 1.HTML页面设计 2.生成每个城市的HTML页面 2.1.HTML页面代码(weatherTemplate.html) 2.2.实例代码-动态生成htm ...

  7. 3D游戏编程 大作业 逃生

    前言 这次的作业是在智能巡逻兵的基础上,改的一个新游戏.本来第七次作业想要效仿学长的3d大作,没想到各种fsm,欧拉角的应用之类的看得我发蒙:之后照着抄也是抄出一堆bug,不得已只好随便敷衍一下,做个 ...

  8. C语言课设电子英汉词典系统(大作业)

    一.设计功能(文章仅供参考) a. 词条录入:即添加单词记录. b. 信息显示:将所有的单词按字母顺序显示. c. 词条修改:对已经输入的单词信息进行修改. d. 词条删除:删除某个单词记录. e. ...

  9. 【2020学年】电子科大Linux高级环境编程大作业

    文章目录 作业设计要求 作业报告要求 作业提交要求 知识点 作业设计要求 总体要求 linux环境下,采用C或C++ 存储一张表,然后能对该表进行查询.添加等操作 上述功能以API的形式提供给应用使用 ...

最新文章

  1. A. Case of the Zeros and Ones
  2. SCROLLINFO结构详解
  3. 一步一步实现iOS QQ第三方登录
  4. 保持用户处于登录状态,加速应用程序启动
  5. sqlserver全文索引问题
  6. Hi3520D UART2和UART3是如何加载到内核的
  7. Hihocoer 1336 - Matrix Sum 二维树状数组
  8. SQL SERVER 数据库日志已满,清理数据库日志的方法
  9. XPS是什么格式?如何编辑?
  10. 堆和栈内存扩展方向问题
  11. mysql dual表用法_mysql dual表的用途及案例
  12. xshell 免费版本下载
  13. coco2dx精灵和背景遮挡_cocos2dx番外篇——更换精灵图片
  14. 二进制(二):十进制转二进制的两种方法
  15. Face Paper:SeNet论文详解
  16. 红米Note3 TWRP-3.4
  17. 深度学习——误差反向传播法
  18. 武汉工程大学图书馆之张丹娜
  19. Ubuntu9.04安装小记,无图有真相
  20. 《顿悟时刻:设计大师访谈录》—第2章Ian Ballantine 关于出版风格短暂的一堂课...

热门文章

  1. oracle添加outline,Oracle Outline的使用
  2. 2020最新中高阶Android面试题总结 下(附解题思路)
  3. 【Vue】错误 : 无法加载文件 C:\Users\Administrator\AppData\Roaming\npm\vue.ps1,因为在此系统上禁止运行脚本的解决方法
  4. 22款奔驰GLE450升级23P驾驶辅助系统,驾驶问题一扫而空
  5. MyBatis标签详解
  6. 我雄鹰一样的男人也咩了,呜呜呜~~~
  7. OO设计模式学习笔记(C#)
  8. linux学习与回顾2
  9. 10款经典Java游戏项目合集,附源码课件
  10. PHP设计模式之策略模式