嵌入式Linux C语言 应用程序开发之通讯录(网络版)

版权声明:版权声明:本文为博主原创文章,博客地址:http://blog.csdn.net/qq_37808895,未经博主允许不得转载。 https://blog.csdn.net/qq_37808895/article/details/88765133

该程序为上一个版本的升级版,可以实现TCP网络通信之间的连接
效果图如下
在这里插入图片描述

库函数

#ifndef ADDRESS_H
#define ADDRESS_H
#define ADDINFO         	1000
#define DELINFO          	1001
#define UPDATEINFO          1002
#define SEARCHINFO          1003
#define SHOWINFO          	1004
#define EXIT            	1005
#define DELETEALL           1006
struct ChatInfo
{
	int cmd;
	char name[32];
	char tel[32];
	char sex[10];
	char loc[15];
};
typedef struct ChatInfo Chat;
#endif

服务端

database.c

#include<stdio.h>
#include<stdlib.h>
#include<sqlite3.h>
#include <string.h>
#include "../address.h"

void InitDataBase()
{
	sqlite3 *ppdb;  //数据库句柄
	
	int ret = sqlite3_open("address.db",&ppdb);
	if(ret!=SQLITE_OK)
	{
		printf("sqlite3_open:%s\n",sqlite3_errmsg(ppdb));
		exit(1);
	}
	char sql[128] = {0};
	sprintf(sql,"create table if not exists address(name text,tel text,sex text,loc text);");
	ret = sqlite3_exec(ppdb,sql,NULL,NULL,NULL);
	if(ret!=SQLITE_OK)
	{
		printf("sqlite3_exec:%s\n",sqlite3_errmsg(ppdb));
		exit(1);
	}
	sqlite3_close(ppdb);
}

void add_info(Chat * c)
{
	sqlite3 *ppdb;
	int ret = sqlite3_open("address.db",&ppdb);
	if(ret != SQLITE_OK)
	{
		printf("sqlite3_open:%s\n",sqlite3_errmsg(ppdb));
		exit(1);
	}
	char sql[120] = {0};
	sprintf(sql,"insert into address values('%s','%s','%s','%s');",c->name,c->tel,c->sex,c->loc);
	ret = sqlite3_exec(ppdb,sql,NULL,NULL,NULL);
	if(ret!=SQLITE_OK)
	{
		printf("sqlite3_exec:%s\n",sqlite3_errmsg(ppdb));
	}
	sqlite3_close(ppdb);
}

int sendinfo(void *pare,int columnCount,char **columnValue,char **columnName)
{
	Chat c;
	int fd=*(int *)pare;
	
	strcpy(c.name,columnValue[0]);
	strcpy(c.tel,columnValue[1]);
	strcpy(c.sex,columnValue[2]);
	strcpy(c.loc,columnValue[3]);
	
	
	
	int ret = send(fd,&c,sizeof(c),0);
	if(-1 == ret)
	{
		perror("send");
		
	}
	return 0;
}

void show_info(int fd)
{
	sqlite3 *ppdb;
	char **result;
	int ret = sqlite3_open("address.db",&ppdb);
	if(ret!=SQLITE_OK)
	{
		printf("sqlite3_open:%s\n",sqlite3_errmsg(ppdb));
		exit(1);
	}
	
	
	
	char sql[128] = "select * from address;";
	ret = sqlite3_exec(ppdb,sql,sendinfo,&fd,NULL);
	if(ret!=SQLITE_OK)
	{
		printf("sqlite3_exec:%s\n",sqlite3_errmsg(ppdb));
		exit(1);
	}
	
	Chat c;
	strcpy(c.name,"bye");
	strcpy(c.tel,"bye");
	
	ret = send(fd,&c,sizeof(c),0);
	if(-1 == ret)
	{
		perror("send");
		exit(1);
	}
	sqlite3_close(ppdb);	
}



void search_info(int fd,Chat * c)
{
	sqlite3 *ppdb;
	char *errmsg;
	int row,column;
	char **result;
	Chat a;

	int ret = sqlite3_open("address.db",&ppdb);
	if(ret != SQLITE_OK)
	{
		printf("sqlite3_open:%s\n",sqlite3_errmsg(ppdb));
		exit(1);
	}
	char sql[120] = {0};
	sprintf(sql,"select name,tel,sex,loc from address where name='%s';",c->name);
	
	
	
	/*ret = sqlite3_exec(ppdb,sql,sendinfo,&fd,NULL);
	if(ret!=SQLITE_OK)
	{
		printf("sqlite3_exec:%s\n",sqlite3_errmsg(ppdb));
		exit(1);
	}*/
	
	
	if(SQLITE_OK != sqlite3_get_table(ppdb,sql,&result,&row,&column,&errmsg))
	{
		printf("查询出错:%s!\n",errmsg);
		exit (0);
	}
	if(row == 0 || column == 0)
	{
		strcpy(a.name,"bye");
		strcpy(a.tel,"bye");	
	}
	else
	{
		
	
		strcpy(a.name,result[4]);
		strcpy(a.tel,result[5]);
		strcpy(a.sex,result[6]);
		strcpy(a.loc,result[7]);
			
		
		
	}
	ret = send(fd,&a,sizeof(a),0);
		if(-1 == ret)
		{
			perror("send");
		}
	sqlite3_free_table(result);
		
	sqlite3_close(ppdb);
}

void del_info(Chat * c)
{
	sqlite3 *ppdb;
	int ret = sqlite3_open("address.db",&ppdb);
	if(ret != SQLITE_OK)
	{
		printf("sqlite3_open:%s\n",sqlite3_errmsg(ppdb));
		exit(1);
	}
	char sql[120] = {0};
	sprintf(sql,"delete from address where name='%s';",c->name);
	ret = sqlite3_exec(ppdb,sql,NULL,NULL,NULL);
	if(ret!=SQLITE_OK)
	{
		printf("sqlite3_exec:%s\n",sqlite3_errmsg(ppdb));
	}
	sqlite3_close(ppdb);
	
	
}


void update_info(int fd,Chat * c)
{
	sqlite3 *ppdb;
	char *errmsg;
	int row,column;
	char **result;
	Chat a;
	int ret = sqlite3_open("address.db",&ppdb);
	if(ret != SQLITE_OK)
	{
		printf("sqlite3_open:%s\n",sqlite3_errmsg(ppdb));
		exit(1);
	}
	char sql[120] = {0};
	sprintf(sql,"update address set tel='%s',sex='%s',loc='%s' where name='%s';",c->tel,c->sex,c->loc,c->name);
	ret = sqlite3_exec(ppdb,sql,NULL,NULL,NULL);
	if(ret!=SQLITE_OK)
	{
		printf("sqlite3_exec:%s\n",sqlite3_errmsg(ppdb));
	}
	sqlite3_close(ppdb);
}


void deleteall(int fd)
{
	sqlite3 *ppdb;
	int ret = sqlite3_open("address.db",&ppdb);
	if(ret!=SQLITE_OK)
	{
		printf("sqlite3_open:%s\n",sqlite3_errmsg(ppdb));
		exit(1);
	}
	char sql[128] = {0};
	sprintf(sql,"delete from address;");
	ret = sqlite3_exec(ppdb,sql,NULL,NULL,NULL);
	if(ret!=SQLITE_OK)
	{
		printf("sqlite3_exec:%s\n",sqlite3_errmsg(ppdb));
		exit(1);
	}
	sqlite3_close(ppdb);
}



socket.c

#include<stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>
#include "../address.h"


int fd[1024] = {0};
pthread_t tid;    //线程号
int InitNet()
{
	struct sockaddr_in server_addr;//客户端信息
	
	//socket
	int sockfd = socket(AF_INET,SOCK_STREAM,0);
	if(-1 == sockfd)
	{
		perror("socket");
		exit(1);
	}
	int opt = 1;
	setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));
	
	memset(&server_addr,0,sizeof(server_addr));
	server_addr.sin_family = AF_INET;
	server_addr.sin_port = htons(2222);
	server_addr.sin_addr.s_addr = INADDR_ANY;
	
	//bind
	int ret = bind(sockfd,(struct sockaddr *)&server_addr,sizeof(server_addr));
	
	if(-1 == ret)
	{
		perror("bind");
		exit(1);
	}
	
	//listen
	ret = listen(sockfd,10);
	if(-1 == ret)
	{
		perror("listen");
		exit(1);
	}
	return sockfd;
}


void exit_client(int fd)
{
	printf("客户端%d下线\n",fd);
	close(fd);
	pthread_exit((void *)0);
}
void * client_handler(void *arg)  //线程函数
{
	Chat c;
	int fd = *(int *)arg;
	while(1)
	{	
		
		int ret = recv(fd,&c,sizeof(c),0);
		if(-1== ret)
		{
			perror("recv");
		}
		switch(c.cmd)
		{
			case ADDINFO:add_info(&c);
				break;
			case DELINFO:search_info(fd,&c);del_info(&c);
				break;
			case UPDATEINFO:search_info(fd,&c);update_info(fd,&c);
				break;
			case SEARCHINFO:search_info(fd,&c);
				break;
			case SHOWINFO:show_info(fd);
				break;
			case EXIT:exit_client(fd);
				break;
			case DELETEALL:deleteall(fd);
				break;
			default:
				break;
		}
		
	}
}
void main_handler(int sockfd)
{
	struct sockaddr_in client_addr;
	int i = 0;
	int length = sizeof(client_addr);
	printf("等待客户端连接\n");
	while(1)
	{
		for(i=0;i<1024;i++)
		{
			if(0 == fd[i])
			{
				break;
			}
		}
		
		fd[i] = accept(sockfd,(struct sockaddr *)&client_addr,&length);
		printf("接受客户端连接%d\n",fd[i]);
		int ret = pthread_create(&tid,NULL,client_handler,&fd[i]);
		
		if(-1 ==ret)
		{
			perror("pthread_create");
			exit(1);
		}
	}
}

main.c

#include <stdio.h>
int main()
{
	int sockfd;
	sockfd = InitNet();
	
	InitDataBase();
	
	main_handler(sockfd);
	
	return 0;
}

客户端

address.c

#include<stdio.h>

#include "../address.h"
void menu()
{
	
	printf("			************************通讯录功能菜单*************************\n");
	printf("			*                                                    	      *\n");
	printf("			*       1.添加通讯录                  2.查看全部联系人        *\n");
	printf("			*       3.查找联系人资料              4.删除联系人            *\n");
	printf("			*       5.修改联系人                  6.清空全部联系人        *\n");
	printf("			*                          0.退出                             *\n");
	printf("			*                                                      	      *\n");
	printf("			***************************************************************\n");
	printf("请输入0-6使用功能:\n");
}


void main_handler(int fd)
{
	char choice[32]={0};
	while(1)
	{
		menu();
		scanf("%s",choice);
		switch(choice[0])
		{
			
			case '1':system("clear");add_info(fd);
				break;
			case '2':system("clear");show_info(fd);
				break;
			case '3':system("clear");search_info(fd);
				break;
			case '4':system("clear");del_info(fd);
				break;
			case '5':system("clear");update_info(fd);
				break;
			case '6':system("clear");deleteall(fd);
				break;
			case '0':system("clear");exit_client(fd);
				break;
			default:
				printf("输入错误请重新输入:\n");
			
		}
	}
}


socket.c

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

int InitNet(int argc,char ** argv)
{
	struct sockaddr_in server_addr;//服务器信息
	
	if(argc != 2)
	{
		printf("usage: client need IP!\n");
		exit(0);
	}
	//socket
	int sockfd = socket(AF_INET,SOCK_STREAM,0);
	
	
	
	if(-1 == sockfd)
	{
		perror("socket");
		exit(1);
	}
	memset(&server_addr,0,sizeof(server_addr));
	server_addr.sin_family = AF_INET;
	server_addr.sin_port = htons(2222);
	server_addr.sin_addr.s_addr = inet_addr(argv[1]);
	
	//NanoPi的地址
	
	//connect
	int ret = connect(sockfd,(struct sockaddr *)&server_addr,sizeof(server_addr));
	if(-1 == ret)
	{
		perror("connect");
		exit(1);
	}
	
	
	return sockfd;
}

void add_info(int fd)
{
	Chat c;
	printf("请输入姓名 电话 性别 地址:\n");
	scanf("%s%s%s%s",c.name,c.tel,c.sex,c.loc);
	
	c.cmd = ADDINFO;
	int ret = send(fd,&c,sizeof(c),0);
	if(-1 ==ret)
	{
		perror("send");
	}
	
	printf("信息添加成功!\n");
}
void exit_client(int fd)
{
	Chat c;
	c.cmd = EXIT;
	int ret = send(fd,&c,sizeof(c),0);
	
	if(-1 == ret)
	{
		perror("send");
	}
	close(fd);
	exit(0);
	
	
}

void show_info(int fd)
{
	Chat c;
	int n=0;
	c.cmd = SHOWINFO;
	int ret = send(fd,&c,sizeof(c),0);
	
	if(-1 == ret)
	{
		perror("send");
		exit(1);
	}
	printf("所有联系人如下:\n");
	while(1)
	{
		memset(&c,0,sizeof(c));
		ret = recv(fd,&c,sizeof(c),0);
		if(-1 == ret)
		{
			perror("recv");
		}
		
		if(!strcmp(c.name,"bye")&&!strcmp(c.tel,"bye"))
		{
			break;
		}
		else
		{
			printf("姓名:%s\n",c.name);
			printf("电话:%s\n",c.tel);
			printf("性别:%s\n",c.sex);
			printf("地址:%s\n",c.loc);
			printf("\n");
			n++;
		}
		
	}
	if(n == 0)
	{
		printf("联系人为空!\n");
		return;
		
	}
	
	
	
	
	
}


void search_info(int fd)
{
	Chat c;
	printf("请输入要查找的联系人姓名:\n");
	scanf("%s",c.name);
	
	c.cmd = SEARCHINFO;
	int ret = send(fd,&c,sizeof(c),0);
	if(-1 ==ret)
	{
		perror("send");
	}
	memset(&c,0,sizeof(c));
	ret = recv(fd,&c,sizeof(c),0);
	if(-1 == ret)
	{
		perror("recv");
	}
	if(!strcmp(c.name,"bye"))
	{
		printf("查询为空\n");
	}
	else
	{
		printf("\n查询结果如下:\n");
		printf("姓名:%s\n",c.name);
		printf("电话:%s\n",c.tel);
		printf("性别:%s\n",c.sex);
		printf("地址:%s\n",c.loc);
		printf("\n");
	}
	
	
	
}

void del_info(int fd)
{
	Chat c;
	printf("请输入要删除的联系人姓名:\n");
	scanf("%s",c.name);
	
	c.cmd = DELINFO;
	int ret = send(fd,&c,sizeof(c),0);
	if(-1 ==ret)
	{
		perror("send");
	}
	
	
	
	memset(&c,0,sizeof(c));
	ret = recv(fd,&c,sizeof(c),0);
	if(-1 == ret)
	{
		perror("recv");
	}
	if(!strcmp(c.name,"bye"))
	{
		printf("该联系人不存在\n");
	}
	else
	{
		printf("联系人删除成功!\n");
	}
	
	
	
	
	
}



void update_info(int fd)
{
	Chat c;
	printf("请输入要修改的联系人姓名和修改后的信息:\n");
	scanf("%s%s%s%s",c.name,c.tel,c.sex,c.loc);
	
	c.cmd = UPDATEINFO;
	int ret = send(fd,&c,sizeof(c),0);
	if(-1 ==ret)
	{
		perror("send");
	}
	memset(&c,0,sizeof(c));
	ret = recv(fd,&c,sizeof(c),0);
	if(-1 == ret)
	{
		perror("recv");
	}
	if(!strcmp(c.name,"bye"))
	{
		printf("该联系人不存在\n");
	}
	else
	{
		printf("联系人修改成功!\n");
	}
}



void deleteall(int fd)
{
	Chat c;
	c.cmd=DELETEALL;
	int ret = send(fd,&c,sizeof(c),0);
	
	if(-1 == ret)
	{
		perror("send\n");
		exit(1);
	}
	
	printf("联系人清空完毕!\n");
}

main.c

#include<stdio.h>
int main(int argc,char ** argv)
{	
	int sockfd;
	sockfd = InitNet();
	
	printf("连接服务器成功!\n");
	main_handler(sockfd);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_37808895/article/details/88765133