该程序为上一个版本的升级版,可以实现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;
}