【1】服务器代码
#include "head.h"
fd_set rdfs;
int num = 1;
sqlite3 *db;
sqlite3 *mdb;
int init_server(int port); // 初始化服务器
void Register(PACK *msg); // 注册
// void *handler(void *arg); // 线程函数
void Login(PACK *msg); // 上线
void Send_out(PACK *msg); // 寄快递
void Search(PACK *msg); // 客户端查快递
int callback(void *arg, int num, char **value, char **name);
void Change_express(PACK *msg); // 更改快递信息
void Cancel_express(PACK *msg); // 取消快递
void Change_user(PACK *msg); // 修改用户信息
void Delete_user(PACK *msg); // 注销
void Send_express(PACK *msg); // 快递员送快递
void Search_status(PACK *msg); // 快递员按状态查快递
void Histroy(PACK *msg); // 查历史记录
char *errmsg = NULL;
char sql[1024];
int main(int argc, char const *argv[])
{
pthread_t tid;
// 创建表
fd_set tempfs;
// 可以连接多个客户端(监听键盘0和sockfd)
int maxfd, acceptfd;
int ret, rev;
char buf[256] = {0};
PACK msg;
// 如果不传递端口,那么使用默认端口8888
int port = 8888;
if (argc > 1)
{
port = atoi(argv[1]);
}
// 初始化服务器
int sockfd = init_server(port);
printf("init ok\n");
// 打开数据库
if (sqlite3_open("./user.db", &db) != SQLITE_OK)
{
fprintf(stderr, "open err:%s", sqlite3_errmsg(db));
return -1;
}
if (sqlite3_open("./msg.db", &mdb) != SQLITE_OK)
{
fprintf(stderr, "open err:%s", sqlite3_errmsg(mdb));
return -1;
}
printf("open ok\n");
// 操作
// char *errmsg = NULL;
// 创建表
if (sqlite3_exec(db, "create table user(name char primary key,password char);", NULL, NULL, &errmsg))
{
fprintf(stderr, "creat user err:%s\n", errmsg);
// return -1;
}
//
if (sqlite3_exec(mdb, "create table info(status int,order_n long,sender char,\
send_addr char,send_tel long,reciver char,recive_addr char,recive_tel long,\
weight float,good char,price float );",
NULL, NULL, &errmsg))
{
fprintf(stderr, "creat info err:%s\n", errmsg);
// return -1;
}
if (sqlite3_exec(mdb, "create table his(status int,order_n long,stime char ,rtime char);",
NULL, NULL, &errmsg))
{
fprintf(stderr, "creat his err:%s\n", errmsg);
// return -1;
}
// 清空表
FD_ZERO(&rdfs);
FD_ZERO(&tempfs);
// 将文件描述符添加到表中
FD_SET(sockfd, &rdfs);
maxfd = sockfd;
while (1)
{
tempfs = rdfs;
ret = select(maxfd + 1, &tempfs, NULL, NULL, NULL);
if (ret < 0)
{
perror("select err");
return -1;
}
if (FD_ISSET(sockfd, &tempfs))
{
acceptfd = accept(sockfd, NULL, NULL);
if (acceptfd < 0)
{
perror("accept err");
return -1;
}
printf("accept ok\n");
// printf("ip:%s port:%d\n", inet_ntoa(caddr.sin_addr), ntohs(caddr.sin_port));
/*心跳包*/
msg.acceptfd = acceptfd;
FD_SET(acceptfd, &rdfs);
if (maxfd < acceptfd)
maxfd = acceptfd;
// pthread_create(&tid, NULL, handler, &msg);
// pthread_detach(tid);
}
for (int i = sockfd + 1; i <= maxfd; i++)
{
if (FD_ISSET(i, &tempfs))
{
// 处理客户端请求
rev = recv(i, &msg, sizeof(msg), 0);
msg.acceptfd = i;
if (rev < 0)
{
perror("recv err");
/*心跳包错误检测*/
return -1;
}
else if (rev == 0)
{
printf("client exit\n");
close(i);
FD_CLR(i, &rdfs);
// if (i == maxfd)
// maxfd--;
while (!FD_ISSET(maxfd, &rdfs))
maxfd--;
}
else
{
printf("%s:%c\n", msg.name, msg.type);
switch (msg.type)
{
case 'R':
Register(&msg);
break;
case 'L':
Login(&msg);
break;
case 'S':
Send_out(&msg);
break;
case 'F':
Search(&msg);
break;
case 'P':
Change_express(&msg);
break;
case 'C':
Cancel_express(&msg);
break;
case 'U':
Change_user(&msg);
break;
case 'D':
Delete_user(&msg);
break;
case 'E':
Send_express(&msg);
break;
case 'A':
Search_status(&msg);
break;
case 'H':
Histroy(&msg);
break;
default:
break;
}
}
}
}
}
return 0;
}
int init_server(int port) // 创建监听套接字
{
int sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0)
{
perror("socket failed");
exit(2);
}
// 设置地址重用
int opt = 1;
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
struct sockaddr_in local;
local.sin_family = AF_INET;
local.sin_port = htons(port);
local.sin_addr.s_addr = INADDR_ANY;
if (bind(sock, (struct sockaddr *)&local, sizeof(local)) < 0)
{
perror("bind failed");
exit(3);
}
if (listen(sock, 5) < 0)
{
perror("listen failed");
exit(4);
}
return sock;
}
/**
* @brief 服务器处理注册
* 得到用户输入用户名和密码并拼接sql语句
* 执行sql语句
* 封装执行结果并回发客户端
*/
void Register(PACK *msg)
{
sprintf(sql, "insert into user values('%s','%s');", msg->name, msg->paaswd);
printf("%s\n", sql);
if (sqlite3_exec(db, sql, NULL, NULL, &errmsg))
{
fprintf(stderr, "insert err:%s\n", errmsg);
return;
}
strcpy(msg->buf, "注册成功");
printf("%s\n", msg->buf);
send(msg->acceptfd, msg, sizeof(PACK), 0);
return;
}
/**
* @brief 服务器处理登录
* 得到用户输入用户名和密码并拼接sql语句
* 执行sql语句
* 判断输入的用户名以及密码是否正确
* 封装执行结果并回发客户端
*/
void Login(PACK *msg)
{
sprintf(sql, "select * from user where name = '%s' and password = '%s';", msg->name, msg->paaswd);
printf("%s\n", sql);
char **result = NULL;
int row = 0, column = 0;
sqlite3_get_table(db, sql, &result, &row, &column, &errmsg);
printf("%d\n", row);
if (row == 0)
strcpy(msg->buf, "用户名或密码错误");
else
strcpy(msg->buf, "登录成功");
send(msg->acceptfd, msg, sizeof(PACK), 0);
sqlite3_free_table(result);
return;
}
/**
* @brief 服务器寄快递
* 得到用户输入快递信息,
* 根据货物重量计算快递价钱,系统给出随机快递单号
* 将快递信息拼接sql语句
* 执行sql语句
* 并将快递信息添加到历史记录表中
* 返回执行信息给客户端
*/
void Send_out(PACK *msg)
{
time_t t;
struct tm *tm;
time(&t);
tm = localtime(&t);
srand((unsigned int)time(NULL)); // 获取随机数种子
msg->msgg.order = rand(); // 生成随机数
char ttime[1024];
sprintf(ttime, "%d-%d-%d %d", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour);
sprintf(sql, "insert into his values (%d,%ld,'%s',0);",
msg->msgg.status, msg->msgg.order, ttime);
printf("%s\n", sql);
if (sqlite3_exec(mdb, sql, NULL, NULL, &errmsg))
{
fprintf(stderr, "insert err:%s\n", errmsg);
return;
}
memset(sql, 0, sizeof(sql));
msg->msgg.price = msg->msgg.weight * 12; // 快递价钱
msg->msgg.status = 0;
sprintf(sql, "insert into info values(%d,%ld,'%s','%s',%ld,'%s','%s',%ld,%f,'%s',%f);", msg->msgg.status, msg->msgg.order, msg->msgg.sender, msg->msgg.send_addr, msg->msgg.send_tel, msg->msgg.reciver, msg->msgg.recive_addr, msg->msgg.recive_tel, msg->msgg.weight, msg->msgg.goods, msg->msgg.price);
if (sqlite3_exec(mdb, sql, NULL, NULL, &errmsg))
{
fprintf(stderr, "insqert err:%s\n", errmsg);
return;
}
strcpy(msg->buf, "寄件成功");
printf("%s\n", msg->buf);
send(msg->acceptfd, msg, sizeof(PACK), 0);
}
/**
* @brief 服务器处理查询快递请求
* 得到用户输入查询信息拼接sql语句
* 执行sql语句
* 回调函数将查询到的信息发送给客户端
*/
void Search(PACK *msg)
{
sprintf(sql, "select * from info where send_tel = %ld;", msg->msgg.send_tel);
if (sqlite3_exec(mdb, sql, callback, "hello", &errmsg) != 0)
{
fprintf(stderr, "select err:%s\n", errmsg);
return;
}
printf("select okk\n");
// 专门用于查询数据的函数:sqlite3_get_table
// row:行
// column:列
char **result = NULL;
int row = 0, column = 0;
if (sqlite3_get_table(mdb, sql, &result, &row, &column, &errmsg) != 0)
{
perror("查询失败\n");
return;
}
memset(sql, 0, sizeof(sql));
// strcpy(msg->buf, "查询成功");
// send(msg->acceptfd, msg, sizeof(PACK), 0);
int k = 11;
printf("row:%d column:%d\n", row, column);
if (row != 0)
{
for (int i = 1; i <= row; i++)
{
for (int j = 0; j < column; j++)
{
strcat(sql, result[k++]);
sql[strlen(sql)] = ' ';
}
sql[strlen(sql)] = '\n';
}
send(msg->acceptfd, sql, sizeof(sql), 0);
printf("查询成功\n");
}
else
{
strcpy(sql, "查询失败");
send(msg->acceptfd, sql, sizeof(sql), 0);
}
return;
}
/**
* @brief 回调函数
*/
int callback(void *arg, int num, char **value, char **name)
{
// 每查询到一条符合条件的数据就会调用一次函数
static int i = 1;
printf("%s:%d\n", (char *)arg, i++);
// num:列数
// value:值
// name:列名
for (int j = 0; j < num; j++)
{
printf("%s ", name[j]);
}
putchar(10);
for (int j = 0; j < num; j++)
{
printf("%s ", value[j]);
}
putchar(10);
printf("***************************************\n");
return 0; // 必须存在,不然sqlite_exec函数会报错
}
/**
* @brief 服务器处理修改快递信息请求
* 得到用户输入的要修改的快递信息并拼接sql语句
* 执行sql语句
* 执行结果发送给客户端
*/
void Change_express(PACK *msg)
{
char sqlstr[1024];
char *errmsg;
sprintf(sqlstr, "update info set send_tel=%ld , send_addr =\"%s\" where order_n=%ld;",
msg->msgg.send_tel, msg->msgg.send_addr, msg->msgg.order);
if (sqlite3_exec(mdb, sqlstr, NULL, NULL, &errmsg))
{
fprintf(stderr, "update err:%s\n", errmsg);
strcpy(msg->buf, "fail err!!!");
}
else
{
strcpy(msg->buf, "updata ok!!!");
}
printf("%s\n", msg->buf);
send(msg->acceptfd, msg, sizeof(PACK), 0);
return;
}
/**
* @brief 服务器处理取消快递信息请求
* 得到用户输入的要取消的快递信息并拼接sql语句
* 执行sql语句
* 执行结果发送给客户端
*/
void Cancel_express(PACK *msg)
{
sprintf(sql, "delete from info where order_n = %ld;", msg->msgg.order);
if (sqlite3_exec(mdb, sql, NULL, NULL, &errmsg) != 0)
{
fprintf(stderr, "delete err:%s\n", errmsg);
return;
}
else
{
strcpy(msg->buf, "删除成功");
}
printf("%s\n", msg->buf);
send(msg->acceptfd, msg, sizeof(PACK), 0);
return;
}
/**
* @brief 服务器处理修改用户信息请求
* 得到用户输入的要修改的信息并拼接sql语句
* 执行sql语句
* 执行结果发送给客户端
*/
void Change_user(PACK *msg)
{
sprintf(sql, "update user set password = '%s' where name = '%s';", msg->paaswd, msg->name);
if (sqlite3_exec(db, sql, NULL, NULL, &errmsg) != 0)
{
fprintf(stderr, "update err:%s\n", errmsg);
return;
}
else
{
strcpy(msg->buf, "修改成功");
}
printf("%s\n", msg->buf);
send(msg->acceptfd, msg, sizeof(PACK), 0);
return;
}
/**
* @brief 服务器处理要注销用户信息请求
* 得到用户输入的要注销的用户信息并拼接sql语句
* 执行sql语句查询输入信息是否正确
* 执行sql语句从表里删除客户信息
* 执行结果发送给客户端
*/
void Delete_user(PACK *msg)
{
sprintf(sql, "delete from user where name = '%s';", msg->name);
if (sqlite3_exec(db, sql, NULL, NULL, &errmsg) != 0)
{
fprintf(stderr, "delete err:%s\n", errmsg);
return;
}
else
{
strcpy(msg->buf, "注销成功");
}
printf("%s\n", msg->buf);
send(msg->acceptfd, msg, sizeof(PACK), 0);
return;
}
/**
* @brief 服务器处理要送达请求
* 得到用户输入的要送达快递的信息并拼接sql语句
* 执行sql语句修改快递信息为送达
* 执行sql语句将送达信息更新到历史记录表中
* 执行结果发送给客户端
*/
void Send_express(PACK *msg)
{
msg->msgg.status = 1;
sprintf(sql, "update his set status = %d where order_n = %ld", msg->msgg.status, msg->msgg.order); // 更新历史记录表
if (sqlite3_exec(mdb, sql, NULL, NULL, &errmsg) != 0)
{
fprintf(stderr, "update err:%s\n", errmsg);
return;
}
sprintf(sql, "update info set status = %d where order_n = %ld", msg->msgg.status, msg->msgg.order);
if (sqlite3_exec(mdb, sql, NULL, NULL, &errmsg) != 0)
{
fprintf(stderr, "update err:%s\n", errmsg);
return;
}
else
{
strcpy(msg->buf, "快递已送达");
}
printf("%s\n", msg->buf);
send(msg->acceptfd, msg, sizeof(PACK), 0);
return;
}
/**
* @brief 服务器处理快递员根据快递是否送达状态查询快递信息请求
* 得到用户输入的要查询的状态并拼接sql语句
* 执行sql语句
* 回调函数将查询到的信息发送给客户端
*/
void Search_status(PACK *msg)
{
sprintf(sql, "select * from info where order_n = %ld;", msg->msgg.order);
if (sqlite3_exec(mdb, sql, callback, "hello", &errmsg) != 0)
{
fprintf(stderr, "select err:%s\n", errmsg);
return;
}
printf("select okk\n");
// 专门用于查询数据的函数:sqlite3_get_table
// row:行
// column:列
char **result = NULL;
int row = 0, column = 0;
if (sqlite3_get_table(mdb, sql, &result, &row, &column, &errmsg) != 0)
{
perror("查询失败\n");
return;
}
memset(sql, 0, sizeof(sql));
// strcpy(msg->buf, "查询成功");
// send(msg->acceptfd, msg, sizeof(PACK), 0);
int k = 11;
printf("row:%d column:%d\n", row, column);
strcpy(sql, result[k]);
send(msg->acceptfd, sql, sizeof(sql), 0);
printf("查询成功\n");
return;
}
/**
* @brief 服务器处理查询历史记录请求
* 得到用户输入的要查询的选项查询信息并拼接sql语句
* 执行sql语句
* 回调函数将查询到的信息发送给客户端
*/
void Histroy(PACK *msg)
{
char sql[1024];
char *errmsg;
if (!strncmp(msg->buf, "all", 1))
sprintf(sql, "select * from his;");
// sqlite3_exec(mdb, "select * from his;", callback, msg, &errmsg);
else
sprintf(sql, "select * from his where stime='%s';", msg->buf);
printf("%s\n", sql);
char **result = NULL;
int row = 0, column = 0;
if (sqlite3_get_table(mdb, sql, &result, &row, &column, &errmsg) != 0)
{
perror("查询失败\n");
return;
}
memset(sql, 0, sizeof(sql));
// strcpy(msg->buf, "查询成功");
// send(msg->acceptfd, msg, sizeof(PACK), 0);
int k = 4;
printf("row:%d column:%d\n", row, column);
if (row != 0)
{
for (int i = 1; i <= row; i++)
{
for (int j = 0; j < column; j++)
{
strcat(sql, result[k++]);
sql[strlen(sql)] = ' ';
}
sql[strlen(sql)] = '\n';
}
send(msg->acceptfd, sql, sizeof(sql), 0);
printf("查询成功\n");
}
else
{
strcpy(sql, "查询失败");
send(msg->acceptfd, sql, sizeof(sql), 0);
}
return;
}
【2】 用户端代码
#include "head.h"
int flag = 0; // 标志位,区分一级界面和二级界面
void show();
void show2();
void Register(PACK *msg);
void Login(PACK *msg);
void Send_out(PACK *msg);
void Search(PACK *msg);
void Change_express(PACK *msg);
void Cancel_express(PACK *msg);
void Change_user(PACK *msg);
void Delete_user(PACK *msg);
int sockfd;
int main(int argc, char const *argv[])
{
char info[128] = {0};
char ip[128] = "192.168.253.150";
int port = 8888;
// 1.创建流式套接字
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
{
perror("socket err");
return -1;
}
printf("sockfd:%d\n", sockfd);
// 2.打开配置文件,读取ip地址和端口号
// 3.填充结构体
struct sockaddr_in saddr;
saddr.sin_family = AF_INET;
saddr.sin_port = htons(port);
saddr.sin_addr.s_addr = inet_addr(ip);
// 4.请求连接
if (connect(sockfd, (struct sockaddr *)&saddr, sizeof(saddr)) < 0)
{
perror("connect err");
return -1;
}
printf("connect ok\n");
// 5.发送消息
PACK msg;
// msg.acceptfd = sockfd;
while (1)
{
msg.acceptfd = sockfd;
if (!flag)
show(); // 登录前
else
show2(); // 登录后
printf("请输入:");
scanf("%c", &msg.type);
getchar();
printf("msg.type:%c\n", msg.type);
switch (msg.type)
{
case 'R':
Register(&msg); // 注册
break;
case 'L':
Login(&msg); // 登录
break;
case 'S':
Send_out(&msg); // 寄快递
break;
case 'F':
Search(&msg); // 查快递
break;
case 'P':
Change_express(&msg); // 修改快递信息
break;
case 'C':
Cancel_express(&msg); // 取消订单
break;
case 'U':
Change_user(&msg); // 修改用户信息
break;
case 'D':
Delete_user(&msg); // 注销用户
break;
case 'Q':
flag = 0; // 返回一级菜单
break;
default:
break;
}
}
// 6.关闭
close(sockfd);
return 0;
}
void show()
{
printf("**R:注册**\n");
printf("**L:登录**\n");
printf("**D:注销**\n");
}
void show2()
{
printf("**F:查快递**\n");
printf("**S:寄快递**\n");
printf("**C:取消订单**\n");
printf("**U:修改用户信息**\n");
printf("**P:修改快递信息**\n");
printf("**Q:返回一级菜单**\n");
}
/**
* @brief 客户端注册
* 用户输入用户名和密码
* 封装消息
* 发送
* 接收并输出结果
*/
void Register(PACK *msg)
{
printf("请输入用户名:");
scanf("%s", msg->name);
getchar();
// fgets(msg->name, sizeof(msg->name), stdin);
// if (msg->name[strlen(msg->name) - 1] == '\n')
// msg->name[strlen(msg->name) - 1] = '\0';
printf("请输入密码:");
scanf("%s", msg->paaswd);
getchar();
// fgets(msg->paaswd, sizeof(msg->paaswd), stdin);
// if (msg->paaswd[strlen(msg->paaswd) - 1] == '\n')
// msg->paaswd[strlen(msg->paaswd) - 1] = '\0';
printf("name:%s pass:%s\n", msg->name, msg->paaswd);
send(sockfd, msg, sizeof(PACK), 0);
recv(sockfd, msg, sizeof(PACK), 0);
printf("%s\n\n", msg->buf);
return;
}
/**
* @brief 客户端登录
* 用户输入用户名和密码
* 封装消息
* 发送
* 接收并输出结果
*
*/
void Login(PACK *msg)
{
while (1)
{
printf("请输入用户名:");
// fgets(msg->name, sizeof(msg->name), stdin);
// if (msg->name[strlen(msg->name) - 1] == '\n')
// msg->name[strlen(msg->name) - 1] = '\0';
scanf("%s", msg->name);
getchar();
printf("请输入密码:");
// fgets(msg->paaswd, sizeof(msg->paaswd), stdin);
// if (msg->paaswd[strlen(msg->paaswd) - 1] == '\n')
// msg->paaswd[strlen(msg->paaswd) - 1] = '\0';
scanf("%s", msg->paaswd);
getchar();
send(sockfd, msg, sizeof(PACK), 0);
recv(sockfd, msg, sizeof(PACK), 0);
if (strcmp(msg->buf, "登录成功") == 0)
{
printf("%s\n\n", msg->buf);
flag = 1;
break;
}
else
{
printf("%s\n\n", msg->buf);
}
}
return;
}
/**
* @brief 客户端寄快递
* 输入发件人姓名,地址,电话;收件人姓名,地址,电话;货物重量,名称
* 发送
* 接收并输出结果
*/
void Send_out(PACK *msg)
{
printf("请输入发件人姓名、地址、电话:");
scanf("%s%s%ld", msg->msgg.sender, msg->msgg.send_addr, &(msg->msgg.send_tel));
getchar();
printf("请输入收件人姓名、地址、电话:");
scanf("%s%s%ld", msg->msgg.reciver, msg->msgg.recive_addr, &(msg->msgg.recive_tel));
getchar();
printf("请输入货物重量、名称:");
scanf("%f%s", &(msg->msgg.weight), msg->msgg.goods);
getchar();
send(sockfd, msg, sizeof(PACK), 0);
recv(sockfd, msg, sizeof(PACK), 0);
printf("%s\n\n", msg->buf);
}
/**
* @brief 客户端查询
* 输入要查询订单的手机号
* 发送
* 接收并输出查询结果
*/
void Search(PACK *msg)
{
char sql[1024] = {0};
printf("请输入要查询订单的手机号:");
scanf("%ld", &(msg->msgg.send_tel));
getchar();
send(sockfd, msg, sizeof(PACK), 0);
// printf("%s\n", msg->buf);
recv(sockfd, sql, sizeof(sql), 0);
if (strcmp(sql, "查询失败") != 0)
{
printf("订单状态 订单号 发件人姓名 地址 电话 收件人姓名 地址 电话 货物重量 名称\n");
printf("%s\n\n", sql);
}
else
{
printf("%s\n", sql);
}
return;
}
/**
* @brief 客户端修改快递信息
* 输入要修改快递单号及快递信息的电话和地址
* 发送
* 接收并输出结果
*/
void Change_express(PACK *msg)
{
printf("请输入要修改快递单号");
scanf("%ld", &msg->msgg.order);
getchar();
printf("请输入要修改快递信息发件人的电话和地址");
scanf("%ld %s", &msg->msgg.send_tel, msg->msgg.send_addr);
getchar();
send(msg->acceptfd, msg, sizeof(PACK), 0);
recv(msg->acceptfd, msg, sizeof(PACK), 0);
printf("%s\n", msg->buf);
return;
}
/**
* @brief 客户端取消寄件
* 输入要取消快递单号
* 发送
* 接收并输出结果
*/
void Cancel_express(PACK *msg)
{
printf("请输入要取消的订单号:");
scanf("%ld", &(msg->msgg.order));
getchar();
send(sockfd, msg, sizeof(PACK), 0);
recv(sockfd, msg, sizeof(PACK), 0);
printf("%s\n\n", msg->buf);
return;
}
/**
* @brief 客户端修改用户信息
* 输入要修改的密码
* 发送
* 接收并输出结果
*/
void Change_user(PACK *msg)
{
printf("请输入要修改的用户名:");
scanf("%s", msg->name);
getchar();
printf("请输入要修改的密码:");
scanf("%s", msg->paaswd);
getchar();
send(sockfd, msg, sizeof(PACK), 0);
recv(sockfd, msg, sizeof(PACK), 0);
printf("%s\n\n", msg->buf);
return;
}
/**
* @brief 客户端注销用户信息
* 输入要注销的用户名、密码
* 发送
* 接收并输出结果
*/
void Delete_user(PACK *msg)
{
printf("请输入要删除的用户名:");
scanf("%s", msg->name);
getchar();
printf("请输入密码:");
scanf("%s", msg->paaswd);
getchar();
send(sockfd, msg, sizeof(PACK), 0);
recv(sockfd, msg, sizeof(PACK), 0);
printf("%s\n\n", msg->buf);
return;
}
【3】快递员端代码
#include "head.h"
int flag = 0;
void show();
void show2();
void Register(PACK *msg);
void Login(PACK *msg);
void Search_status(PACK *msg);
void Change_user(PACK *msg);
void Delete_user(PACK *msg);
void Send_express(PACK *msg);
void Histroy(PACK *msg);
int sockfd;
int main(int argc, char const *argv[])
{
char info[128] = {0};
char ip[128] = "192.168.253.150";
// char port[32] = {0};
int port = 8888;
// 1.创建流式套接字
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
{
perror("sockfd err");
return -1;
}
// 2.打开配置文件,读取ip地址和端口号
// 3.填充结构体
struct sockaddr_in saddr;
saddr.sin_family = AF_INET;
saddr.sin_port = htons(port);
saddr.sin_addr.s_addr = inet_addr(ip);
// 4.请求连接
if (connect(sockfd, (struct sockaddr *)&saddr, sizeof(saddr)) < 0)
{
perror("connect err");
return -1;
}
printf("connect ok\n");
// 5.发送消息
PACK msg;
while (1)
{
msg.acceptfd = sockfd;
if (!flag)
show();
else
show2();
printf("请输入:");
scanf("%c", &msg.type);
getchar();
printf("msg.type:%c\n", msg.type);
switch (msg.type)
{
case 'R':
Register(&msg); // 注册
break;
case 'L':
Login(&msg); // 登录
break;
case 'E':
Send_express(&msg); // 送快递
break;
case 'A':
Search_status(&msg); // 查快递
break;
case 'H':
Histroy(&msg); // 查询历史记录
break;
case 'U':
Change_user(&msg); // 修改用户信息
break;
case 'D':
Delete_user(&msg); // 注销用户
break;
case 'Q':
flag = 0; // 返回一级菜单
break;
default:
break;
}
}
// 6.关闭
close(sockfd);
return 0;
}
// 一级界面显示
void show()
{
printf("**R:注册**\n");
printf("**L:登录**\n");
printf("**D:注销**\n");
}
// 二级界面显示
void show2()
{
printf("**A:查快递**\n");
printf("**E:送快递**\n");
printf("**U:修改用户信息**\n");
printf("**H:查询历史订单记录**\n");
printf("**Q:返回上一级菜单**\n");
}
/**
* @brief 客户端注册
* 用户输入用户名和密码
* 封装消息
* 发送
* 接收并输出结果
*/
void Register(PACK *msg)
{
printf("请输入用户名:");
fgets(msg->name, sizeof(msg->name), stdin);
if (msg->name[strlen(msg->name) - 1] == '\n')
msg->name[strlen(msg->name) - 1] = '\0';
printf("请输入密码:");
fgets(msg->paaswd, sizeof(msg->paaswd), stdin);
if (msg->paaswd[strlen(msg->paaswd) - 1] == '\n')
msg->paaswd[strlen(msg->paaswd) - 1] = '\0';
printf("name:%s pass:%s\n", msg->name, msg->paaswd);
send(sockfd, msg, sizeof(PACK), 0);
recv(sockfd, msg, sizeof(PACK), 0);
printf("%s\n\n", msg->buf);
return;
}
/**
* @brief 客户端登录
* 用户输入用户名和密码
* 封装消息
* 发送
* 接收并输出结果
*
*/
void Login(PACK *msg)
{
while (1)
{
printf("请输入用户名:");
// fgets(msg->name, sizeof(msg->name), stdin);
// if (msg->name[strlen(msg->name) - 1] == '\n')
// msg->name[strlen(msg->name) - 1] = '\0';
scanf("%s", msg->name);
getchar();
printf("请输入密码:");
// fgets(msg->paaswd, sizeof(msg->paaswd), stdin);
// if (msg->paaswd[strlen(msg->paaswd) - 1] == '\n')
// msg->paaswd[strlen(msg->paaswd) - 1] = '\0';
scanf("%s", msg->paaswd);
getchar();
send(sockfd, msg, sizeof(PACK), 0);
recv(sockfd, msg, sizeof(PACK), 0);
if (strcmp(msg->buf, "登录成功") == 0)
{
printf("%s\n\n", msg->buf);
flag = 1;
break;
}
else
{
printf("%s\n\n", msg->buf);
}
}
return;
}
/**
* @brief 客户端送快递
* 用户输入要送达的快递单号
* 封装消息
* 发送
* 接收并输出结果
*
*/
void Send_express(PACK *msg)
{
printf("请输入要送达的快递单号:");
scanf("%ld", &(msg->msgg.order));
getchar();
send(sockfd, msg, sizeof(PACK), 0);
recv(sockfd, msg, sizeof(PACK), 0);
printf("%s\n\n", msg->buf);
return;
}
/**
* @brief 客户端查询快递状态
* 输入要查询订单号
* 发送
* 接收并输出查询结果
*/
void Search_status(PACK *msg)
{
char sql[1024] = {0};
printf("请输入要查询的订单号:");
scanf("%ld", &(msg->msgg.order));
getchar();
send(sockfd, msg, sizeof(PACK), 0);
recv(sockfd, sql, sizeof(sql), 0);
if (strcmp(sql, "1") == 0)
{
printf("已送达\n\n");
}
else
{
printf("未送达\n\n");
}
return;
}
/**
* @brief 客户端修改用户信息
* 输入要修改的密码
* 发送
* 接收并输出结果
*/
void Change_user(PACK *msg)
{
printf("请输入要修改的用户名:");
scanf("%s", msg->name);
getchar();
printf("请输入要修改的密码:");
scanf("%s", msg->paaswd);
getchar();
send(sockfd, msg, sizeof(PACK), 0);
recv(sockfd, msg, sizeof(PACK), 0);
printf("%s\n\n", msg->buf);
return;
}
/**
* @brief 客户端注销用户信息
* 输入要注销的用户名、密码
* 发送
* 接收并输出结果
*/
void Delete_user(PACK *msg)
{
printf("请输入要删除的用户名:");
scanf("%s", msg->name);
getchar();
printf("请输入密码:");
scanf("%s", msg->paaswd);
getchar();
send(sockfd, msg, sizeof(PACK), 0);
recv(sockfd, msg, sizeof(PACK), 0);
printf("%s\n\n", msg->buf);
return;
}
/**
* @brief 客户端查询历史订单
* 输入要查询的选项,查询所有订单还是根据时间戳查询
* 发送
* 接收并输出查询结果
*/
void Histroy(PACK *msg)
{
char sql[1024];
printf("请输入要查询的选项:\n");
printf("注意:输入all查询所有订单 或 输入time:(要查询的时间):\n");
memset(msg->buf, 0, 128);
// scanf("%s", msg->buf);
fgets(msg->buf, 128, stdin);
if (msg->buf[strlen(msg->buf) - 1] == '\n')
msg->buf[strlen(msg->buf) - 1] = '\0';
send(sockfd, msg, sizeof(PACK), 0);
recv(sockfd, sql, sizeof(sql), 0);
if (strcmp(sql, "查询失败") != 0)
{
printf("订单状态 订单号 寄出时间 送达时间\n");
printf("%s\n\n", sql);
}
else
{
printf("%s\n", sql);
}
}
【4】头文件
#ifndef __HEAD_H__
#define __HEAD_H__
#include<stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <sys/select.h>
#include <pthread.h>
#include <sqlite3.h>
#include <errno.h>
#include <netinet/tcp.h>
struct order_msg
{
int status; //0:表示未完成订单 1:表示已完成订单
long order; //订单号,由服务器端生成
char sender[32]; //发送人
char send_addr[64]; //发送地址
long send_tel; //发送电话
char reciver[32]; //收件人
char recive_addr[64]; //收件地址
long recive_tel; //收件人电话
float weight; //货物重量
char goods[32]; //货物名称
float price; //快递费用
};
typedef struct pack_head
{
int acceptfd;
unsigned char type; //消息类型
unsigned char usertype; //用户类型:1:用户 2:快递员
char name[32]; //用户名
char paaswd[32]; //密码
char buf[32]; //调试信息
struct order_msg msgg; //单号信息
} PACK;
#endif
【5】makefile
all:
gcc server.c -o s -lsqlite3
gcc d_client.c -o d
gcc u_client.c -o u
.PHONY:clean
clean:
rm -f *.o
标签:void,编程,华清,速递,sql,printf,msg,sizeof,PACK From: https://blog.csdn.net/dghbs/article/details/142467623今天的分享就到这里结束啦,如果有哪里写的不好的地方,请指正。
如果觉得不错并且对你有帮助的话点个关注支持一下吧!