基于C语言tcp协议实现在线英语词典

涉及知识

        本项目主要涉及了,C语言,IO进线程,网络编程的一些知识。

主要组成部分

客户端

        客户端主要的功能是对用户的登录账号和密码进行识别,判断账号和密码是否存在,如果不存在提醒用户账号密码不存在,如果存在则判断账号密码是否匹配,如果账号密码匹配则登陆系统成功,失败则进行提示,当成功进入系统后可执行单词的查询和历史记录的查看操作。

下面是实现上诉功能的代码:

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


int main(int argc, char *argv[])
{ 
    int sockfd=socket(AF_INET,SOCK_STREAM,0);
    if(sockfd<0)
    {
        perror("socket");
        return -1;
    }
    char ip_data[20]={0},port_data[20]={0};
    system("clear");
    printf("\033[35m         请输入服务器ip地址         \033[0m\n");
    gets(ip_data);
    printf("\033[35m          请输入服务器端口          \033[0m\n");
    gets(port_data);
    system("sl");
    struct sockaddr_in addr;
    addr.sin_family         =AF_INET;
    addr.sin_port           =htons(atoi(port_data));
    addr.sin_addr.s_addr    =inet_addr(ip_data);
    if(-1==connect(sockfd,(struct sockaddr *)&addr,sizeof(addr)))
    {
        perror("connect");
        return -1;
    }
    while(1)
    {
    	system("clear");
        printf("\033[5;35m*************************************************\033[0m\n");
        printf("\033[5;35m**\033[0m                    1注册                    \033[5;35m**\033[0m\n");
        printf("\033[5;35m**\033[0m                    2登陆                    \033[5;35m**\033[0m\n");
        printf("\033[5;35m**\033[0m               输入quit结束服务              \033[5;35m**\033[0m\n");
        printf("\033[5;35m*************************************************\033[0m\n");
        char query_data[128]={0};
        scanf("%s",query_data);
        sendto(sockfd,query_data,sizeof(query_data),0,NULL,0);
        if(strcmp(query_data,"quit")==0)
        {
            system("clear");
            printf("\033[7;31m***************服务已结束,感谢你的使用**********************\033[0m\n");
            break;
        }
	else
	{
	    if(strcmp(query_data,"1")==0)
	    {
	    	  system("clear");
		  char account_number[32]={0},the_code[32]={0};
		  printf("\033[5;35m                 进入注册系统                      \033[0m\n");
		  printf("\033[35m            输入你的账号(32位以内)                 \033[0m\n");
		  scanf("%s",account_number);
		  sendto(sockfd,account_number,sizeof(account_number),0,NULL,0);
		  printf("\033[35m            输入你的密码(32位以内)                  \033[0m\n");
		  scanf("%s",the_code);
		  sendto(sockfd,the_code,sizeof(the_code),0,NULL,0);
		  bzero(query_data,0);
		  recvfrom(sockfd,query_data,sizeof(query_data),0,NULL,NULL);
		  printf("%s\n",query_data);
		  if(strcmp(query_data,"a")==0)
		  {
		  	printf("\033[5;31m*************注册成功将返回上一级******************\033[0m\n");
		  	sleep(2);
		  	continue;
		  }
		  else if(strcmp(query_data,"b")==0)
		  {
		  	printf("\033[5;31m****************打开数据库失败**********************\033[0m\n");
		  	sleep(2);
		  	continue;
		  }
		  else if(strcmp(query_data,"c")==0)
		  {
		  	printf("\033[5;31m****************打开数据库失败**********************\033[0m\n");
		  	sleep(2);
		  	continue;
		  }
		  else if(strcmp(query_data,"d")==0)
		  {
		  	printf("\033[5;31m*******************注册失败************************\033[0m\n");
		  	sleep(2);
		  	continue;
		  }
		  else if(strcmp(query_data,"f")==0)
		  {
		  	printf("\033[5;31m*****************账号查找出错***********************\033[0m\n");
		  	sleep(2);
		  	continue;
		  }
		  else
		  {
		  	printf("\033[5;31m*************账号已存在,请重新输入*****************\033[0m\n");
		  	sleep(2);
		  	continue;
		  }
		  
	    }
	    else if(strcmp(query_data,"2")==0)
	    {
	    	  system("clear");
		  char account_number[32]={0},the_code[32]={0};
		  printf("\033[35m                  进入登陆系统                     \033[0m\n");
		  printf("\033[35m             输入你的账号(32位以内)                \033[0m\n");
		  scanf("%s",account_number);
		  sendto(sockfd,account_number,sizeof(account_number),0,NULL,0);
		  printf("\033[35m             输入你的密码(32位以内)                \033[0m\n");
		  scanf("%s",the_code);
		  sendto(sockfd,the_code,sizeof(the_code),0,NULL,0);
		  recvfrom(sockfd,query_data,sizeof(query_data),0,NULL,NULL);
		  printf("%s\n",query_data);
		  if(strcmp(query_data,"a")==0)
		  {
		  	system("clear");
		  	printf("\033[5;31m*******************登陆成功************************\033[0m\n");
		  	sleep(2);
		  	if(query_data[0]>=0)
		    	{
		    		while(1)
		    		{
		    			system("clear");
		    			printf("\033[5;35m**********************************************************\033[0m\n");
					printf("\033[5;35m**\033[0m                 当前在查询系统                       \033[5;35m**\033[0m\n");
					printf("\033[5;35m**\033[0m          0退出   1查询单词   2查看历史查询记录       \033[5;35m**\033[0m\n");
					printf("\033[5;35m**********************************************************\033[0m\n");
					scanf("%s",query_data);
					sendto(sockfd,query_data,sizeof(query_data),0,NULL,0);
					if(strcmp(query_data,"0")==0)
					{
						printf("\033[5;31m*******************将返回上一级**********************\033[0m\n");
						sleep(2);
						break;
					}
					else if(strcmp(query_data,"1")==0)
					{
						system("clear");
						printf("\033[5;31m**********现在正在进行单词查询,输入0可返回上一级************\033[0m\n");
						sleep(3);
						while(1)
						{
							char data_flag[128]={0};
							printf("\033[31minpit>\033[0m");
							scanf("%s",query_data);
							strcpy(data_flag,query_data);
							sendto(sockfd,query_data,sizeof(query_data),0,NULL,0);  
							if(strcmp(query_data,"0")==0)
							{
								printf("\033[5;31m**********************将返回上一级***********************\033[0m\n");
								sleep(2);
								break;
							}
							recvfrom(sockfd,query_data,sizeof(query_data),0,NULL,NULL);
							if(strcmp(query_data,"a")==0)
							{
								recvfrom(sockfd,query_data,sizeof(query_data),0,NULL,NULL);
								printf("\033[35m%s: %s\n\033[0m",data_flag,query_data);
								history_data(account_number,data_flag,query_data);
							}
							else if(strcmp(query_data,"d")==0)
							{
								printf("\033[5;31m**********************查无此单词***********************\033[0m\n");
								continue;
							}
							else
							{
								printf("\033[5;31m**********************未知错误,请联系管理人员***********************\033[0m\n");
								continue;
							}
						}
					}
					else if(strcmp(query_data,"2")==0)
					{
						system("clear");
						char back_data[4096]={0};
						printf("\033[5;31m********************正在进行历史记录查询**********************\033[0m\n");
						history_seek(account_number,back_data);
						printf("\033[35%s\033[0m\n",back_data);
						printf("\033[5;31m********************0返回上一级其他数字继续********************\033[0m\n");
						int flag_l;
						scanf("%d",&flag_l);
						sendto(sockfd,&flag_l,1,0,NULL,0); 
						if(flag_l==0)
						{
							break;
						}
						else
						{
							continue;
						}
						
					} 
					else
					{
						printf("\033[5;31m*********************输入错误请重新输入************************\033[0m\n");
						sleep(2);
						continue;
					}
				}

						
		    	}
		  	continue;
		  }
		  else if(strcmp(query_data,"b")==0)
		  {
		  	printf("\033[5;31m****************打开数据库失败**********************\033[0m\n");
		  	sleep(2);
		  	break;
		  }
		  else if(strcmp(query_data,"e")==0)
		  {
		  	printf("\033[5;31m*******************无此账号*************************\033[0m\n");
		  	sleep(2);
		  	continue;
		  }
		  else if(strcmp(query_data,"c")==0)
		  {
		  	printf("\033[5;31m*******************匹对失败*************************\033[0m\n");
		  	continue;
		  }
		  else
		  {
		  	printf("\033[5;31m*******************密码错误*************************\033[0m\n");
		  	sleep(2);
		  	continue;
		  }
	    }	
	 else 
	 {
	 	printf("\033[5;31m**********************输入错误,重新输入***************************\033[0m\n");
	 	sleep(2);
	 	continue;
	 }
     }
    }
	
    close(sockfd);
    return 0;
} 

服务器

        在服务器中首先需要做的就是判断是否有新的客户端进行连接,如果有新的客户端进行了连接,则需要循环读取判断客户端是否有新的信息发送过来,如果有则需要将接收客户端发过来的信息进行识别判断,如果在数据库中找到相应的单词返回单词的含义返回给客户端,若没发现对应单词含义则返回错误提示符号。

下面是服务器的相应代码:

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <netinet/in.h>
#include <netinet/ip.h> 
#include <string.h>
#include <stdlib.h>
#include "database_usrdata_lan.h"
#include "database_usrdata.h"
#include "database_seek.h"
#include "database_import.h"



int tcp_init(int arg);
int wait_accept(int arg);

int tcp_init(int hton)
{
    int sockfp=socket(AF_INET,SOCK_STREAM,0);
    if(sockfp<0)
    {
        perror("socket");
        return -1;
    }
    int opt = 1;
    if(setsockopt(sockfp, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0){
        perror("setsockopt");
        return -1;
    }
    struct sockaddr_in addr;
    addr.sin_family     =AF_INET;
    addr.sin_port       =htons(hton);
    addr.sin_addr.s_addr=htonl(INADDR_ANY);
    if(bind(sockfp,(struct sockaddr*)&addr,sizeof(addr))<0)
    {
        perror("bind");
        return -1;
    }
    if(listen(sockfp,12)<0)
    {
        perror("listen");
        return -1;
    }
    return sockfp;
}

int wait_accept(int arg)
{
    struct sockaddr_in caddr;
    socklen_t len=sizeof(caddr);
    int fp=accept(arg,(struct sockaddr*)&caddr,&len);
    if(fp<0)
    {
        perror("accept");
        return -1;
    }
    return fp;
}

int main(int argc, char *argv[])
{
    system("clear");
    int fp=tcp_init(2234);
    if(fp<0)
    {
        printf("tcp_init:create not sucess");
        return -1;
    }
    database_import();
    printf("服务器初始化成功,等待客户端连接\n");
    pid_t len_flag;
    while(1)
    {
	int fq=wait_accept(fp);
	if(fq<0)
	{
		   continue;
	}
	printf("有客户端连接成功\n");
	len_flag=fork();
    	if(len_flag==0)
    	{
		while(1)
		{
		    char buf[128]={0};
		    int num=recvfrom(fq,buf,sizeof(buf),0,NULL,NULL);
		    if(num<0)
		    {
		        perror("sendto");
		        break;
		    }
		    else if(num==0)
		    {
		        continue;
		    }
		    else
		    {
			if(strcmp(buf,"1")==0)
			{
			    char account_number[32]={0},the_code[32]={0};
			    if(recvfrom(fq,account_number,sizeof(account_number),0,NULL,NULL)==0)
			    {
			    	printf("有客户端断开连接\n");
			    	break;
			    }
			    if(recvfrom(fq,the_code,sizeof(the_code),0,NULL,NULL)==0)
			    {
			    	printf("有客户端断开连接\n");
			    	break;
			    }
			    bzero(buf,0);
			    buf[0]=database_usrdata(account_number,the_code);
			    sendto(fq,buf,sizeof(buf),0,NULL,0);
			    continue;
			}
			else if(strcmp(buf,"2")==0)
			{
			    char account_number[32]={0},the_code[32]={0};
			    if(recvfrom(fq,account_number,sizeof(account_number),0,NULL,NULL)==0)
			    {
			    	printf("有客户端断开连接\n");
			    	break;
			    }
			    if(recvfrom(fq,the_code,sizeof(the_code),0,NULL,NULL)==0)
			    {
			    	printf("有客户端断开连接\n");
			    	break;
			    }
			    bzero(buf,0);
			    buf[0]=database_usrdata_lan(account_number,the_code);
			    printf("%s\n",buf);
			    sendto(fq,buf,sizeof(buf),0,NULL,0);	    
			    if(strcmp(buf,"a")==0)
			    {
				    while(1)
				    {
				    	if(recvfrom(fq,buf,sizeof(buf),0,NULL,NULL)==0)
				    	{
				    		break;
				    	}
				    	if(strcmp(buf,"1")==0)
					{
					    	while(1)
					    	{
					    	    char buf_seek[128]={0},flag_seek[128]={0};
					    	    if(recvfrom(fq,buf,sizeof(buf),0,NULL,NULL)==0)
					    	    {
					    	    	break;
					    	    }
					    	    if(strcmp(buf,"0")==0)
					    	    {
					    	    	break;
					    	    }
					    	    flag_seek[0]=database_seek(buf,buf_seek);
					    	    sendto(fq,flag_seek,sizeof(flag_seek),0,NULL,0);
					    	    if(strcmp(flag_seek,"a")==0)
					    	    {
					    	    	printf("%s\n",buf_seek);
					    	    	sendto(fq,buf_seek,sizeof(buf_seek),0,NULL,0);
					    	    }
					    	    else
					    	    {
					    	    	continue;
					    	    }
					    	}
					 }
					 else if(strcmp(buf,"2")==0)
					 {
					    int flag_l;
					    if(recvfrom(fq,&flag_l,1,0,NULL,NULL)==0)
					    {
					    	break;
					    }
					    if(flag_l==0)
					    {
					    	break;
					    }
					    else
					    {
					    	continue;
					    }
					 }
					 else if(strcmp(buf,"0")==0)
					 {
					    	break;
					 }
					 else
					 {
					    	continue;
					 }
				    	
				    }
				}
				else
				{
					continue;
				}
			    }
		    else
		    {
		    	 printf("有客户端断开连接\n");
			 break;
		    }
		    
		}
	      }
	      printf("有客户端断开连接\n");
	      close(fq);
	   }
	}
   close(fp);	
   return 0;
} 

数据库

        本项目中主要用到的数据是sqlite3,在数据库的操作上主要用到的了数据库的插入和查询。

下面是数据库的插入代码:

#include "database_usrdata.h"

char database_usrdata(char *usr_data, char *usr_lan)
{ 
    sqlite3 *db;
    if(sqlite3_open("database.db",&db)!=SQLITE_OK)
    {
        return 'b';
    }
    char sql[128]={0},**resultp;
    int nrow,ncloumn;
    sprintf(sql,"create table if not exists usrlan_data(name text,content text);");
    if(sqlite3_exec(db,sql,NULL,NULL,NULL)!=SQLITE_OK)
    {
        return 'c';
    }
    sprintf(sql,"select content from usrlan_data where name='%s';",usr_data);
    if(sqlite3_get_table(db,sql,&resultp,&nrow,&ncloumn,NULL)!=SQLITE_OK)
    {
        return 'f';
    }
    if(resultp[ncloumn]==NULL)
    {
    	bzero(sql,0);
    	sprintf(sql,"insert into usrlan_data values('%s','%s');",usr_data,usr_lan);
    	if(sqlite3_exec(db,sql,NULL,NULL,NULL)!=SQLITE_OK)
    	{
        	return 'd';
    	}
    	return 'a';
    }


    return 'e';

} 

数据库查询代码:

#include "database_seek.h"

char database_seek(char *squery_data,char *buf)
{
    sqlite3 *db;
    if(sqlite3_open("database.db",&db)!=SQLITE_OK)
    {
        return 'b';
    }
    char sql[128]={0},**retulse;
    int nrow,ncloumn;
    sprintf(sql,"select content from dictionary where name='%s';",squery_data);
    if(sqlite3_get_table(db,sql,&retulse,&nrow,&ncloumn,NULL)!=SQLITE_OK)
    {
    	sqlite3_close(db);
        return 'c';
    }
    if(ncloumn==0)
    {
     	sqlite3_close(db);
    	return 'd';
    }
    else
    {
    	strcpy(buf,retulse[ncloumn]);
    }
    sqlite3_close(db);
    return 'a';
} 

章末

        以上便是整个英语词典项目的主要内容,完整代码笔者将放置在文章中。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值