一.项目需求
功能描述:
仿照顺丰速运功能,实现一个自己的速递项目。自行定义项目名,最终可以提现到简历中
服务器:
处理客户端的请求,并将数据存入数据库中,客户端请求的数据从数据库进行获取,服务器转发给客户端。
用户客户端:
实现账号的注册、登录、注销、修改用户密码功能,当登录成功时可以寄快递、查快递、修改快递信息、取消订单等功能。
快递员客户端:
实现账号的注册、登录、注销、修改用户密码功能,当登录成功时可以查快递、送快递、查看历史订单等功能。
二.主要的结构体:
struct pack_head{
int fd;//通信的文件描述符
unsigned char type; //消息类型
unsigned char usertype; //用户类型:1:用户 2:快递员
char name[32]; //用户名
char paaswd[32]; //密码
char buf[32]; //调试信息
struct order_msg msg; //单号信息
};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; //快递费用
};
三.流程图
1.服务器流程图:
2.用户客户端流程图:
3.快递员流程图:
四:代码实现
.h文件
//头文件
#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
1.服务器代码:
#include "1.h"
fd_set reads, temp;
int flag = 0;
pack msg;
sqlite3 *db;
void show1(); // 登录前
void show2(); // 登录后
void zhuce(pack *msg); // 注册
void denglu(pack *msg); // 登录
void zhuxiao(pack *msg); // 注销
void chakuaidi(pack *msg); // 查快递
void jikuaidi(pack *msg); // 寄快递
void quxiaodingdan(pack *msg); // 取消订单
void xiugaiyonghumima(pack *msg); // 修改用户信息
void xiugaikuaidixinxi(pack *msg); // 修改快递信息
int main(int argc, char const *argv[])
{
char buf[256];
if (argc != 2)
{
printf("用法 <port>\n");
return -1;
}
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
{
perror("socket err");
return -1;
}
int flags = 1;
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &flags, sizeof(flags)); // 设置地址重用
struct sockaddr_in saddr, caddr;
saddr.sin_family = AF_INET;
saddr.sin_port = htons(atoi(argv[1]));
saddr.sin_addr.s_addr = INADDR_ANY;
;
socklen_t addrlen = sizeof(saddr);
if (bind(sockfd, (struct sockaddr *)&saddr, addrlen) < 0)
{
perror("bind err");
return -1;
}
if (listen(sockfd, 7) < 0)
{
perror("listen err");
return -1;
}
// 创建或打开数据库
if (sqlite3_open("./msg.db", &db) != 0)
{
printf("打开或创建数据库失败:%s", sqlite3_errmsg(db));
return -1;
}
char *errmsg = NULL;
// 创建三个表,分别是用户表,快递信息表,历史记录表
if (sqlite3_exec(db, "create table user(name char,password char);", NULL, NULL, &errmsg))
{
printf("创建用户表失败:%s\n", errmsg);
}
// status订单情况 order订单号 sender发送人 send_addr发送地址 send_tel发送电话 reciver收件人 recive_addr收件地址 recive_tel收件人电话 weight货物重量 goods货物名称 price快递费用
if (sqlite3_exec(db, "create table kuaidixinxi(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))
{
printf("创建快递信息表失败:%s\n", errmsg);
}
// status订单情况 order订单号 stime添加时间 rtime修改时间
if (sqlite3_exec(db, "create table lishijilu(status int,order_n long,stime char ,rtime char);", NULL, NULL, &errmsg))
{
printf("创建历史记录表失败:%s\n", errmsg);
}
FD_ZERO(&reads); //
FD_ZERO(&temp);
FD_SET(sockfd, &reads); // 将 sockfd 文件描述符添加到 readfds 集合中
int max = sockfd;
while (1)
{
temp = reads; // 将 read 文件描述符集合复制到 temp 中,以便 select 函数修改 temp 而不影响 read
int ret = select(max + 1, &temp, NULL, NULL, NULL); // 调用 select 监视文件描述符集合
if (ret < 0)
{
perror("select err");
return -1;
}
if (FD_ISSET(sockfd, &temp)) // 检查是否有新连接到达
{
int acceptfd = accept(sockfd, (struct sockaddr *)&caddr, &addrlen); // 接受新连接
if (acceptfd < 0)
{
perror("accept 失败");
return -1;
}
printf("accept成功\n");
printf("ip:%s port:%d\n", inet_ntoa(caddr.sin_addr), ntohs(caddr.sin_port));
msg.fd = acceptfd; // 将新连接的文件描述符添加到 read 文件描述符集合中
FD_SET(acceptfd, &reads);
if (max < acceptfd) // 更新最大文件描述符值
{
max = acceptfd;
}
}
for (int i = sockfd + 1; i <= max; i++) // 遍历所有可能的文件描述符,检查是否有数据到达
{
if (FD_ISSET(i, &temp))
{
int rev = recv(i, &msg, sizeof(msg), 0);
msg.fd = i;
if (rev < 0)
{
perror("recv失败");
return -1;
}
else if (rev == 0) // 如果 recv 返回 0,表示客户端关闭连接
{
printf("%s退出\n", inet_ntoa(caddr.sin_addr));
FD_CLR(i, &reads); // 从 read 文件描述符集合中移除该文件描述符
close(i);
while (!FD_ISSET(max, &reads)) // 更新最大文件描述符值
{
max--;
}
}
else
{
printf("%s:%c\n", msg.name, msg.type);
if (!flag)
show1(); // 登录前
else
show2(); // 登陆后
printf("请输入:");
scanf("%c", &msg.type); // 消息类型
getchar();
printf("msg.type:%c\n", msg.type);
switch (msg.type)
{
case 'R':
zhuce(&msg); // 注册
break;
case 'L':
denglu(&msg); // 登录
break;
case 'D':
zhuxiao(&msg); // 注销
break;
case 'F':
chakuaidi(&msg); // 查快递
break;
case 'S':
jikuaidi(&msg); // 寄快递
break;
case 'C':
quxiaodingdan(&msg); // 取消订单
break;
case 'U':
xiugaiyonghumima(&msg); // 修改用户信息
break;
case 'P':
xiugaikuaidixinxi(&msg); // 修改快递信息
break;
case 'Q':
flag = 0; // 返回一级菜单
default:
break;
}
}
}
}
}
return 0;
}
void show1() // 登录前
{
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");
}
void zhuce(pack *msg) // 注册
{
memset(msg->buf, 0, sizeof(msg->buf)); // 清空 buf 的内容
char *errmsg = NULL; // 错误信息指针
char sql[128]; // 存储查询语句
char check_sql[128]; // 存储检查用户名是否存在的 SQL 查询语句
char **result = NULL; // 存储查询结果
int rows, columns; // 查询结果的行数和列数
while (1)
{
sprintf(check_sql, "select * from user where name='%s';", msg->name); // 构造检查用户名是否已存在的查询语句
if (sqlite3_get_table(db, check_sql, &result, &rows, &columns, &errmsg) != 0) // 执行查询
{
sprintf(msg->buf, "查询失败: %s", errmsg); // 查询失败,设置错误信息并退出循环
break;
}
if (rows > 0) // 如果查询结果中有行数据,说明用户名已存在
{
sprintf(msg->buf, "用户名已存在");
break;
}
sprintf(sql, "insert into user values('%s','%s');", msg->name, msg->paaswd); // 插入用户信息的语句
if (sqlite3_exec(db, sql, NULL, NULL, &errmsg) != 0) // 执行插入操作
{
sprintf(msg->buf, "err %s", errmsg);
printf("失败\n");
break;
}
else
{
printf("%s\n", sql);
sprintf(msg->buf, "okk!!!");
printf("成功\n");
break;
}
}
send(msg->fd, msg->buf, sizeof(msg->buf), 0); // 发送注册结果信息到客户端
}
void denglu(pack *msg) // 登录
{
memset(msg->buf, 0, sizeof(msg->buf)); // 清空 buf 的内容
char sql[128]; // 存储查询语句
char *errmsg = NULL; // 错误信息指针
char **result = NULL; // 存储查询结果
int rows, columns; // 查询结果的行数和列数
while (1)
{
sprintf(sql, "select * from user where name = '%s' and password = '%s';", msg->name, msg->paaswd); // 构造登录验证查询语句
int sqlget = sqlite3_get_table(db, sql, &result, &rows, &columns, &errmsg); // 查询
if (sqlget != 0) // 查询失败,设置错误信息并退出循环
{
sprintf(msg->buf, "sqlite3_get_table 错误: %s", errmsg);
break;
}
else if (rows > 0) // 查询结果中有数据,登录成功
{
sprintf(msg->buf, "okk");
printf("成功\n");
break;
}
else
{
sprintf(msg->buf, "name or paaswd worng!!");
printf("失败");
break;
}
}
send(msg->fd, msg->buf, strlen(msg->buf), 0); // 发送登录结果信息到客户端
}
void zhuxiao(pack *msg) // 注销
{
memset(msg->buf, 0, sizeof(msg->buf)); // 清空 buf 的内容
char sql[128]; // 存储查询语句
char *errmsg = NULL; // 错误信息指针
char **result = NULL; // 存储查询结果
int rows, columns; // 查询结果的行数和列数
while (1)
{
sprintf(sql, "delete from user where name = '%s';", msg->name); // 构造删除用户信息的语句
if (sqlite3_exec(db, sql, NULL, NULL, &errmsg) != 0) // 执行删除操作
{
sprintf(msg->buf, "注销失败: %s", errmsg);
break;
}
else
{
printf("%s\n", sql);
sprintf(msg->buf, "注销成功");
break;
}
}
send(msg->fd, msg->buf, sizeof(msg->buf), 0); // 发送注销结果信息到客户端
}
void chakuaidi(pack *msg) // 查快递
{
memset(msg->buf, 0, sizeof(msg->buf)); // 清空消息缓冲区
memset(msg->msgg.sender, 0, sizeof(msg->msgg.sender)); // 清空发送人信息
memset(msg->msgg.send_addr, 0, sizeof(msg->msgg.send_addr)); // 清空发送地址
memset(msg->msgg.reciver, 0, sizeof(msg->msgg.reciver)); // 清空收件人信息
memset(msg->msgg.recive_addr, 0, sizeof(msg->msgg.recive_addr)); // 清空收件地址
memset(msg->msgg.goods, 0, sizeof(msg->msgg.goods)); // 清空货物名称
char sql[1024];
char *errmsg = NULL;
char **result = NULL;
int rows, columns;
sprintf(sql, "select * from kuaidixinxi where send_tel = %ld;", msg->msgg.send_tel); // 创建查询语句
int rc = sqlite3_get_table(db, sql, &result, &rows, &columns, &errmsg); // 执行查询
if (rc != 0) // 查询失败,输出错误信息
{
sprintf(msg->buf, "查询失败: %s", errmsg);
}
else
{
if (rows > 0) // 查询到信息,格式化输出
{
for (int i = 1; i <= rows; ++i)
{
strcat(msg->buf, "查询到的信息:");
for (int j = 0; j < columns; ++j)
{
strcat(msg->buf, result[i * columns + j]);
strcat(msg->buf, " ");
}
strcat(msg->buf, "\n");
}
}
else// 没有找到快递信息
{
strcpy(msg->buf, "没有找到该快递信息");
}
}
send(msg->fd, msg->buf, strlen(msg->buf) - 1, 0); // 发送结果到客户端
}
void jikuaidi(pack *msg) // 寄快递
{
memset(msg->buf, 0, sizeof(msg->buf)); // 清空缓冲区
msg->msgg.status = 0; // 设置状态为0(寄出)
msg->msgg.price = msg->msgg.weight * 5; // 计算价格(重量乘以单位价格)
char sql[1024]; // 用于存储插入快递信息的语句
char sql1[1024]; // 用于存储插入历史记录的语句
char *errmsg = NULL; // 错误信息
char **result = NULL; // 查询结果
int rows, columns; // 查询结果的行数和列数
time_t t; // 当前时间
struct tm *tm; // 时间结构体
char stime[100]; // 格式化时间字符串
time(&t); // 获取当前时间
tm = localtime(&t); // 转换为本地时间
msg->msgg.order = t; // 记录订单时间
while (1)
{
sprintf(stime, "%d-%d-%d-%d", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour);// 格式化时间字符串
snprintf(sql, sizeof(sql), "insert into kuaidixinxi 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);// 构造插入快递信息的 SQL 语句
snprintf(sql1, sizeof(sql1), "insert into lishijilu values (%d,%ld,'%s',0);",
msg->msgg.status, msg->msgg.order, stime);// 构造插入历史记录的 SQL 语句
if (sqlite3_exec(db, sql, NULL, NULL, &errmsg) != 0) // 执行插入快递信息的操作
{
sprintf(msg->buf, "寄快递失败: %s", errmsg);
break;
}
else
{
printf("%s\n", sql); // 打印 SQL 语句
}
if (sqlite3_exec(db, sql1, NULL, NULL, &errmsg) != 0)// 执行插入历史记录的操作
{
sprintf(msg->buf, "放入历史记录失败: %s", errmsg);
break;
}
else
{
printf("%s\n", sql1); // 打印语句
sprintf(msg->buf, "寄快递成功");
break;
}
}
send(msg->fd, msg->buf, sizeof(msg->buf), 0);// 发送结果到客户端
}
void quxiaodingdan(pack *msg) // 取消订单
{
memset(msg->buf, 0, sizeof(msg->buf)); // 清空缓冲区
char sql[1024]; // 用于存储删除快递信息的语句
char sql1[1024]; // 用于存储更新历史记录的语句
char *errmsg = NULL; // 错误信息
char **result = NULL; // 查询结果
int rows, columns; // 查询结果的行数和列数
time_t t; // 当前时间
struct tm *tm; // 时间结构体
char rtime[100]; // 格式化时间字符串
time(&t); // 获取当前时间
tm = localtime(&t); // 转换为本地时间
while (1)
{
sprintf(rtime, "%d-%d-%d-%d", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour);// 格式化时间字符串
snprintf(sql, sizeof(sql), "delete from kuaidixinxi where order_n=%ld;", msg->msgg.order);// 创建删除快递信息的 SQL 语句
snprintf(sql1, sizeof(sql1), "update lishijilu set rtime='%s' where order_n=%ld;", rtime, msg->msgg.order);// 创建更新历史记录的 SQL 语句
if (sqlite3_exec(db, sql, NULL, NULL, &errmsg) != 0)// 执行删除操作
{
sprintf(msg->buf, "取消订单失败: %s", errmsg);
break;
}
else
{
printf("%s\n", sql); // 打印语句
}
if (sqlite3_exec(db, sql1, NULL, NULL, &errmsg) != 0) // 执行更新历史记录操作
{
sprintf(msg->buf, "放入历史记录失败: %s", errmsg);
break;
}
else
{
printf("%s\n", sql1); // 打印语句
sprintf(msg->buf, "取消订单成功");
break;
}
}
send(msg->fd, msg->buf, sizeof(msg->buf), 0);// 发送结果到客户端
}
void xiugaiyonghumima(pack *msg) // 修改用户密码
{
memset(msg->buf, 0, sizeof(msg->buf)); // 清空消息缓冲区
char sql[128]; // 用于存储更新用户密码的语句
char *errmsg = NULL; // 错误信息
char **result = NULL; // 查询结果(未使用)
int rows, columns; // 查询结果的行数和列数(未使用)
while (1)
{
sprintf(sql, "update user set password='%s' where name = '%s';", msg->paaswd, msg->name); // 生成更新用户密码的 语句
if (sqlite3_exec(db, sql, NULL, NULL, &errmsg) != 0)
{
sprintf(msg->buf, "修改失败: %s", errmsg);
break;
}
else
{
printf("%s\n", sql);
sprintf(msg->buf, "修改密码成功");
break;
}
}
send(msg->fd, msg->buf, sizeof(msg->buf), 0);
}
void xiugaikuaidixinxi(pack *msg) // 修改快递信息
{
char sql[1024]; // 查询语句
char *errmsg = NULL; // 错误信息
printf("%s\n", msg->msgg.sender); // 打印发送人信息(调试用)
while (1)
{
// 根据 buf 的内容生成相应的 SQL 更新语句
if (strcmp(msg->buf, "发送人") == 0)
{
sprintf(sql, "update kuaidixinxi set sender='%s' where order_n=%ld;", msg->msgg.sender, msg->msgg.order);
memset(msg->buf, 0, sizeof(msg->buf)); // 清空 buf
}
else if (strcmp(msg->buf, "发送地址") == 0)
{
sprintf(sql, "update kuaidixinxi set send_addr='%s' where order_n=%ld;", msg->msgg.send_addr, msg->msgg.order);
memset(msg->buf, 0, sizeof(msg->buf)); // 清空 buf
}
else if (strcmp(msg->buf, "发送人电话") == 0)
{
sprintf(sql, "update kuaidixinxi set send_tel=%ld where order_n=%ld;", msg->msgg.send_tel, msg->msgg.order);
memset(msg->buf, 0, sizeof(msg->buf)); // 清空 buf
}
else if (strcmp(msg->buf, "收件人") == 0)
{
sprintf(sql, "update kuaidixinxi set reciver='%s' where order_n=%ld;", msg->msgg.reciver, msg->msgg.order);
memset(msg->buf, 0, sizeof(msg->buf)); // 清空 buf
}
else if (strcmp(msg->buf, "收件地址") == 0)
{
sprintf(sql, "update kuaidixinxi set recive_addr='%s' where order_n=%ld;", msg->msgg.recive_addr, msg->msgg.order);
memset(msg->buf, 0, sizeof(msg->buf)); // 清空 buf
}
else if (strcmp(msg->buf, "收件人电话") == 0)
{
sprintf(sql, "update kuaidixinxi set recive_tel=%ld where order_n=%ld;", msg->msgg.recive_tel, msg->msgg.order);
memset(msg->buf, 0, sizeof(msg->buf)); // 清空 buf
}
else if (strcmp(msg->buf, "货物重量") == 0)
{
sprintf(sql, "update kuaidixinxi set weight=%f where order_n=%ld;", msg->msgg.weight, msg->msgg.order);
memset(msg->buf, 0, sizeof(msg->buf)); // 清空 buf
}
else if (strcmp(msg->buf, "货物名称") == 0)
{
sprintf(sql, "update kuaidixinxi set good='%s' where order_n=%ld;", msg->msgg.goods, msg->msgg.order);
memset(msg->buf, 0, sizeof(msg->buf)); // 清空 buf
}
msg->msgg.price = msg->msgg.weight * 5;// 计算快递价格
if (sqlite3_exec(db, sql, NULL, NULL, &errmsg) != 0) // 执行查询
{
sprintf(msg->buf, "修改快递信息失败: %s", errmsg);
break;
}
else
{
printf("%s\n", sql);
sprintf(msg->buf, "修改快递信息成功");
break;
}
}
send(msg->fd, msg->buf, sizeof(msg->buf), 0);
}
2.快递员端代码:
#include "1.h" pack msg; int flag = 0; void show1(); // 登录界面 void show2(); void zhuce(pack *msg); // 注册 void denglu(pack *msg); // 登录 void zhuxiao(pack *msg); // 注销 void chakuaidi(pack *msg); // 查快递 void songkuaidi(pack *msg); // 送快递 void xiugaiyonghumima(pack *msg); // 修改用户密码 void chakanlishijilu(pack *msg); // 查看历史记录 void dingdanzhuangtaichaxun(pack*msg); // 订单状态查询 int main(int argc, char const *argv[]) { int sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) { perror("socket err"); return -1; } struct sockaddr_in saddr; saddr.sin_family = AF_INET; saddr.sin_port = htons(atoi(argv[1])); saddr.sin_addr.s_addr = INADDR_ANY; int len = sizeof(saddr); if (connect(sockfd, (struct sockaddr *)&saddr, len) < 0) { perror("connect err"); return -1; } while (1) { memset(msg.buf, 0, sizeof(msg.buf)); msg.usertype = 2; msg.fd = sockfd; if (flag == 0) { show1(); // 登录界面 } if (flag == 1) { show2(); // 快递界面 } printf("请输入:"); scanf(" %c", &msg.type); printf("msg.type:%c\n", msg.type); switch (msg.type) { case 'R': zhuce(&msg); // 注册 break; case 'L': denglu(&msg); // 登录 break; case 'D': zhuxiao(&msg); // 注销用户 break; // case 'A': // dingdanzhuangtaichaxun(&msg); // 订单状态查询 // break; case 'E': songkuaidi(&msg); // 送快递 break; case 'U': xiugaiyonghumima(&msg); // 修改用户密码 break; case 'H': chakanlishijilu(&msg); // 查看历史记录 break; case 'Q': flag = 0; // 返回登录菜单 break; default: break; } } // 6.关闭 close(sockfd); return 0; } void show1() // 登录界面 { 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"); } void zhuce(pack *msg) // 注册 { memset(msg->name, 0, sizeof(msg->name)); memset(msg->paaswd, 0, sizeof(msg->paaswd)); printf("请输入用户名:"); scanf("%s", msg->name); getchar(); printf("请输入用户密码:"); scanf("%s", msg->paaswd); getchar(); send(msg->paaswd, msg, sizeof(*msg), 0); recv(msg->paaswd, msg->buf, sizeof(msg->buf), 0); printf("%s\n", msg->buf); if (strcmp(msg->buf, "注册成功") == 0) { flag = 0; } } void denglu(pack *msg) // 登录 { while (1) { memset(msg->name, 0, sizeof(msg->name)); memset(msg->paaswd, 0, sizeof(msg->paaswd)); printf("请输入用户名:"); scanf("%s", msg->name); getchar(); printf("请输入用户密码:"); scanf("%s", msg->paaswd); getchar(); send(msg->paaswd, msg, sizeof(*msg), 0); recv(msg->paaswd, msg->buf, sizeof(msg->buf), 0); printf("%s\n", msg->buf); if (strcmp(msg->buf, "登录成功") == 0) { flag = 1; break; } if (strcmp(msg->buf, "登录失败") == 0) { continue; } } } void xiugaiyonghumima(pack *msg) // 修改用户密码 { memset(msg->paaswd, 0, sizeof(msg->paaswd)); printf("请输入要修改后的密码:"); scanf("%s", msg->paaswd); getchar(); send(msg->paaswd, msg, sizeof(*msg), 0); recv(msg->paaswd, msg->buf, sizeof(msg->buf), 0); printf("%s\n", msg->buf); if (strcmp(msg->buf, "修改密码成功") == 0) { flag = 0; } } void zhuxiao(pack *msg) // 注销 { memset(msg->name, 0, sizeof(msg->name)); memset(msg->paaswd, 0, sizeof(msg->paaswd)); printf("请输入你要注销的用户名:"); scanf("%s", msg->name); getchar(); printf("请输入用户密码:"); scanf("%s", msg->paaswd); getchar(); send(msg->paaswd, msg, sizeof(*msg), 0); recv(msg->paaswd, msg->buf, sizeof(msg->buf), 0); printf("%s\n", msg->buf); } void songkuaidi(pack *msg) // 送快递 { printf("请输入要送达的快递单号:"); scanf("%ld", &msg->msgg.order); getchar(); send(msg->paaswd, msg, sizeof(*msg), 0); recv(msg->paaswd, msg->buf, sizeof(msg->buf), 0); printf("%s\n", msg->buf); } void dingdanzhuangtaichaxun(pack *msg) // 订单状态查询 { printf("请输入要查询订单的状态(0未送达,1已送达):"); scanf("%d", &msg->msgg.status); getchar(); send(msg->paaswd, msg, sizeof(*msg), 0); recv(msg->paaswd, msg->buf, sizeof(msg->buf), 0); printf("%s\n", msg->buf); } void chakanlishijilu(pack *msg) // 查看历史记录 { char leixing[100]; while (1) { printf("请输入要查询的选项(all:查询所有订单;time:(要查询的时间)\n"); scanf("%s", leixing); getchar(); if (strcmp(leixing, "all") == 0) { strcpy(msg->buf, "all"); send(msg->paaswd, msg, sizeof(*msg), 0); memset(msg->buf, 0, sizeof(msg->buf)); recv(msg->paaswd, msg->buf, sizeof(msg->buf), 0); break; } else if (strcmp(leixing, "time") == 0) { printf("请输入要查询的时间:"); scanf("%s", msg->buf); getchar(); send(msg->paaswd, msg, sizeof(*msg), 0); memset(msg->buf, 0, sizeof(msg->buf)); recv(msg->paaswd, msg->buf, sizeof(msg->buf), 0); break; } else { printf("输入错误,请重新输入\n"); continue; } } printf("%s\n", msg->buf); }
3.用户端代码:
#include "1.h"
pack msg;
int flag = 0;
void show1(); // 登录界面
void show2(); // 快递界面
void zhuce(pack *msg); // 注册
void denglu(pack *msg); // 登录
void zhuxiao(pack *msg); // 注销
void chakuaidi(pack *msg); // 查快递
void jikuaidi(pack *msg); // 寄快递
void quxiaodingdan(pack *msg); // 取消订单
void xiugaiyonghumima(pack *msg); // 修改用户密码
void xiugaikuaidixinxi(pack *msg); // 修改快递信息
int main(int argc, char const *argv[])
{
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
{
perror("socket err");
return -1;
}
struct sockaddr_in saddr;
saddr.sin_family = AF_INET;
saddr.sin_port = htons(atoi(argv[1]));
saddr.sin_addr.s_addr = INADDR_ANY;
int len = sizeof(saddr);
if (connect(sockfd, (struct sockaddr *)&saddr, len) < 0)
{
perror("connect err");
return -1;
}
while (1)
{
memset(msg.buf, 0, sizeof(msg.buf));
msg.usertype = 1;
msg.fd = sockfd;
if (flag == 0)
{
show1(); // 登录界面
}
if (flag == 1)
{
show2(); // 快递界面
}
printf("请输入:");
scanf(" %c", &msg.type);
printf("msg.type:%c\n", msg.type);
switch (msg.type)
{
case 'R':
zhuce(&msg); // 注册
break;
case 'L':
denglu(&msg); // 登录
break;
case 'S':
jikuaidi(&msg); // 寄快递
break;
case 'F':
chakuaidi(&msg); // 查快递
break;
case 'P':
xiugaikuaidixinxi(&msg); // 修改快递信息
break;
case 'C':
quxiaodingdan(&msg); // 取消订单
break;
case 'U':
xiugaiyonghumima(&msg); // 修改用户密码
break;
case 'D':
zhuxiao(&msg); // 注销用户
break;
case 'Q':
flag = 0; // 返回登录菜单
break;
default:
break;
}
}
// 6.关闭
close(sockfd);
return 0;
}
void show1() // 登录界面
{
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");
}
void zhuce(pack *msg) // 注册
{
memset(msg->name, 0, sizeof(msg->name));
memset(msg->paaswd, 0, sizeof(msg->paaswd));
printf("请输入用户名:");
scanf("%s", msg->name);
getchar();
printf("请输入用户密码:");
scanf("%s", msg->paaswd);
getchar();
send(msg->fd, msg, sizeof(*msg), 0);
recv(msg->fd, msg->buf, sizeof(msg->buf), 0);
printf("%s\n", msg->buf);
if (strcmp(msg->buf, "注册成功") == 0)
{
flag = 0;
}
}
void denglu(pack *msg) // 登录
{
while (1)
{
memset(msg->name, 0, sizeof(msg->name));
memset(msg->paaswd, 0, sizeof(msg->paaswd));
printf("请输入用户名:");
scanf("%s", msg->name);
getchar();
printf("请输入用户密码:");
scanf("%s", msg->paaswd);
getchar();
send(msg->paaswd, msg, sizeof(*msg), 0);
recv(msg->paaswd, msg->buf, sizeof(msg->buf), 0);
printf("%s\n", msg->buf);
if (strcmp(msg->buf, "登录成功") == 0)
{
flag = 1;
break;
}
if (strcmp(msg->buf, "登录失败") == 0)
{
continue;
}
}
}
void jikuaidi(pack *msg) // 寄快递
{
memset(msg->msgg.sender, 0, sizeof(msg->msgg.sender));
memset(msg->msgg.send_addr, 0, sizeof(msg->msgg.send_addr));
memset(msg->msgg.reciver, 0, sizeof(msg->msgg.reciver));
memset(msg->msgg.recive_addr, 0, sizeof(msg->msgg.recive_addr));
memset(msg->msgg.goods, 0, sizeof(msg->msgg.goods));
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);
send(msg->fd, msg, sizeof(*msg), 0);
recv(msg->fd, msg->buf, sizeof(msg->buf), 0);
printf("%s\n", msg->buf);
if (strcmp(msg->buf, "寄快递成功") == 0)
{
flag = 1;
}
}
void chakuaidi(pack *msg) // 查快递
{
printf("请输入发件人电话:");
scanf("%ld", &msg->msgg.send_tel);
getchar();
send(msg->fd, msg, sizeof(*msg), 0);
recv(msg->fd, msg->buf, sizeof(msg->buf), 0);
printf("%s\n", msg->buf);
}
void xiugaikuaidixinxi(pack *msg) // 修改快递信息
{
char leixing[100];
printf("请输入要修改的快递单号:");
scanf("%ld", &msg->msgg.order);
getchar();
while (1)
{
printf("请输入要修改的内容(发送人S,发送地址S1,发送人电话S2,收件人R,收件地址R1,收件人电话R2,货物重量W,货物名称G):");
scanf("%s", leixing);
getchar();
if (strcmp(leixing, "发送人") == 0)
{
memset(msg->msgg.sender, 0, sizeof(msg->msgg.sender));
printf("请输入要修改的信息:");
scanf("%s", msg->msgg.sender);
getchar();
printf("%s\n", msg->msgg.sender);
strcpy(msg->buf, "发送人");
break;
}
else if (strcmp(leixing, "发送地址") == 0)
{
memset(msg->msgg.send_addr, 0, sizeof(msg->msgg.send_addr));
printf("请输入要修改的信息:");
scanf(" %s", msg->msgg.send_addr);
strcpy(msg->buf, "发送地址");
break;
}
else if (strcmp(leixing, "发送人电话") == 0)
{
printf("请输入要修改的信息:");
scanf(" %ld", &msg->msgg.send_tel);
strcpy(msg->buf, "发送人电话");
break;
}
else if (strcmp(leixing, "收件人") == 0)
{
memset(msg->msgg.reciver, 0, sizeof(msg->msgg.reciver));
printf("请输入要修改的信息:");
scanf(" %s", msg->msgg.reciver);
strcpy(msg->buf, "收件人");
break;
}
else if (strcmp(leixing, "收件地址") == 0)
{
memset(msg->msgg.recive_addr, 0, sizeof(msg->msgg.recive_addr));
printf("请输入要修改的信息:");
scanf(" %s", msg->msgg.recive_addr);
strcpy(msg->buf, "收件地址");
break;
}
else if (strcmp(leixing, "收件人电话") == 0)
{
printf("请输入要修改的信息:");
scanf(" %ld", &msg->msgg.recive_tel);
strcpy(msg->buf, "收件人电话");
break;
}
else if (strcmp(leixing, "货物重量") == 0)
{
printf("请输入要修改的信息:");
scanf(" %f", &msg->msgg.weight);
strcpy(msg->buf, "货物重量");
break;
}
else if (strcmp(leixing, "货物名称") == 0)
{
memset(msg->msgg.goods, 0, sizeof(msg->msgg.goods));
printf("请输入要修改的信息:");
scanf(" %s", msg->msgg.goods);
strcpy(msg->buf, "货物名称");
break;
}
else
{
printf("要修改的内容不存在,请重新输入\n");
continue;
}
}
send(msg->fd, msg, sizeof(*msg), 0);
recv(msg->fd, msg->buf, sizeof(msg->buf), 0);
printf("%s\n", msg->buf);
}
void quxiaodingdan(pack *msg) // 取消订单
{
printf("请输入要取消的快递单号:");
scanf("%ld", &msg->msgg.order);
getchar();
send(msg->fd, msg, sizeof(*msg), 0);
recv(msg->fd, msg->buf, sizeof(msg->buf), 0);
printf("%s\n", msg->buf);
}
void xiugaiyonghumima(pack *msg) // 修改用户密码
{
memset(msg->paaswd, 0, sizeof(msg->paaswd));
printf("请输入要修改后的密码:");
scanf("%s", msg->paaswd);
getchar();
send(msg->fd, msg, sizeof(*msg), 0);
recv(msg->fd, msg->buf, sizeof(msg->buf), 0);
printf("%s\n", msg->buf);
if (strcmp(msg->buf, "修改密码成功") == 0)
{
flag = 0;
}
}
void zhuxiao(pack *msg) // 注销
{
memset(msg->name, 0, sizeof(msg->name));
memset(msg->paaswd, 0, sizeof(msg->paaswd));
printf("请输入你要注销的用户名:");
scanf("%s", msg->name);
getchar();
printf("请输入用户密码:");
scanf("%s", msg->paaswd);
getchar();
send(msg->fd, msg, sizeof(*msg), 0);
recv(msg->fd, msg->buf, sizeof(msg->buf), 0);
printf("%s\n", msg->buf);
}
标签:编程,速递,网络,char,msgg,printf,msg,sizeof,buf
From: https://blog.csdn.net/weixin_63207763/article/details/142287073