项目:华清速递

一:设计思路:

1.1:基于tcp协议,实现两个客户端和服务器的通信,仿照顺丰快递的模式,大致分为快递员客户端和用户客户端,实现相关操作

1.2:用户客户端,主要进行登录,注销,注册,寄快递等相关操作

1.3:快递员客户端:进行收快递,送快递,以及历史记录查询等相关操作

1.4:服务器:通过tcp 协议哥select函数实现并发式服务器,,在函数体内部,新建数据库,库中包括三个表,分别是用户账号密码表,快递信息表以及历史记录表,编写相应子函数,进行调用,在连接客户端的基础上,进行相关操作

二:相关协议族

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 fd;unsigned char type;     //消息类型unsigned char usertype; //用户类型:1:用户  2:快递员char name[32];          //用户名char password[32];        //密码char buf[1024];           //调试信息struct order_msg msg;  //单号信息
} head;

三:服务器代码实现:

#include "head.h"head msg;
sqlite3 *db;
fd_set readfd, tempfd;void Register(head *msg) // 注册
{memset(msg->buf, 0, sizeof(msg->buf));char *errmsg = NULL;char sql[128];char check_sql[128];char **result = NULL;int hang, lie;while (1){ // 检查用户名是否已存在sprintf(check_sql, "select * from user where name='%s';", msg->name);if (sqlite3_get_table(db, check_sql, &result, &hang, &lie, &errmsg) != 0){sprintf(msg->buf, "查询失败: %s", errmsg);break;}if (hang > 0){sprintf(msg->buf, "用户名已存在");break;}// 执行插入操作sprintf(sql, "insert into user values('%s','%s');", msg->name, msg->password);if (sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK){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 login(head *msg) // 登录
{memset(msg->buf, 0, sizeof(msg->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->password);// 执行 SQL 查询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, "登录成功");break;}else{sprintf(msg->buf, "登录失败");break;}}send(msg->fd, msg->buf, strlen(msg->buf), 0);
}void Send_an_express_deliver(head *msg) // 寄快递
{memset(msg->buf, 0, sizeof(msg->buf));msg->msg.status = 0;msg->msg.price = msg->msg.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->msg.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 Express_information values (%d,%ld,'%s','%s',%ld,'%s','%s',%ld,%f,'%s',%f);", msg->msg.status, msg->msg.order, msg->msg.sender, msg->msg.send_addr, msg->msg.send_tel, msg->msg.reciver, msg->msg.recive_addr, msg->msg.recive_tel, msg->msg.weight, msg->msg.goods, msg->msg.price);snprintf(sql1, sizeof(sql1), "insert into lishijilu values (%d,%ld,'%s',0);", msg->msg.status, msg->msg.order, stime);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 cancel(head *msg) // 注销
{memset(msg->buf, 0, sizeof(msg->buf));char sql[128];char *errmsg = NULL;char **result = NULL;int hang, lie;while (1){sprintf(sql, "delete from user where name = '%s';", msg->name); // 删除所在位置信息// 查询if (sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK){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 Modify_user_password(head *msg) // 修改用户密码
{memset(msg->buf, 0, sizeof(msg->buf));char sql[128];char *errmsg = NULL;char **result = NULL;int hang, lie;while (1){sprintf(sql, "update user set password='%s' where name = '%s';", msg->password, msg->name);// 查询if (sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK){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 Order_status_inquiry(head *msg) // 订单状态查询
{memset(msg->buf, 0, sizeof(msg->buf));memset(msg->msg.sender, 0, sizeof(msg->msg.sender));memset(msg->msg.send_addr, 0, sizeof(msg->msg.send_addr));memset(msg->msg.reciver, 0, sizeof(msg->msg.reciver));memset(msg->msg.recive_addr, 0, sizeof(msg->msg.recive_addr));memset(msg->msg.goods, 0, sizeof(msg->msg.goods));char sql[1024];char *errmsg = NULL;char **result = NULL;int hang, lie;// 创建 SQL 查询sprintf(sql, "select * from Express_information where status = %d;", msg->msg.status);// 执行 SQL 查询int rc = sqlite3_get_table(db, sql, &result, &hang, &lie, &errmsg);if (rc != 0){sprintf(msg->buf, "查询失败: %s", errmsg);}else{if (hang > 0){for (int i = 1; i <= hang; ++i){strcat(msg->buf, "查询到的信息:");for (int j = 0; j < lie; ++j){strcat(msg->buf, result[i * lie + j]);strcat(msg->buf, " ");}strcat(msg->buf, "\n");}}}send(msg->fd, msg->buf, strlen(msg->buf) - 1, 0);
}void Modify_courier_information(head *msg) // 修改快递信息
{char sql[1024];char *errmsg = NULL;printf("%s\n", msg->msg.sender);while (1){if (strcmp(msg->buf, "发送人") == 0){sprintf(sql, "update Express_information set sender='%s' where order_n=%ld;", msg->msg.sender, msg->msg.order);memset(msg->buf, 0, sizeof(msg->buf));}if (strcmp(msg->buf, "发送人地址") == 0){sprintf(sql, "update Express_information set send_addr='%s' where order_n=%ld;", msg->msg.send_addr, msg->msg.order);memset(msg->buf, 0, sizeof(msg->buf));}if (strcmp(msg->buf, "发送人电话") == 0){sprintf(sql, "update Express_information set send_tel=%ld where order_n=%ld;", msg->msg.send_tel, msg->msg.order);memset(msg->buf, 0, sizeof(msg->buf));}if (strcmp(msg->buf, "收件人") == 0){sprintf(sql, "update Express_information set reciver='%s' where order_n=%ld;", msg->msg.reciver, msg->msg.order);memset(msg->buf, 0, sizeof(msg->buf));}if (strcmp(msg->buf, "收件人地址") == 0){sprintf(sql, "update Express_information set recive_addr='%s' where order_n=%ld;", msg->msg.recive_addr, msg->msg.order);memset(msg->buf, 0, sizeof(msg->buf));}if (strcmp(msg->buf, "发送人电话") == 0){sprintf(sql, "update  Express_information set recive_tel=%ld where order_n=%ld;", msg->msg.recive_tel, msg->msg.order);memset(msg->buf, 0, sizeof(msg->buf));}if (strcmp(msg->buf, "货物重量") == 0){sprintf(sql, "update Express_information set weight=%f where order_n=%ld;", msg->msg.weight, msg->msg.order);memset(msg->buf, 0, sizeof(msg->buf));}if (strcmp(msg->buf, "货物名字") == 0){sprintf(sql, "update Express_information set goods='%s' where order_n=%ld;", msg->msg.goods, msg->msg.order);memset(msg->buf, 0, sizeof(msg->buf));}msg->msg.price = msg->msg.weight * 2;// 查询修改信息if (sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK){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 Check_courie(head *msg) // 查快递
{memset(msg->buf, 0, sizeof(msg->buf));memset(msg->msg.sender, 0, sizeof(msg->msg.sender));memset(msg->msg.send_addr, 0, sizeof(msg->msg.send_addr));memset(msg->msg.reciver, 0, sizeof(msg->msg.reciver));memset(msg->msg.recive_addr, 0, sizeof(msg->msg.recive_addr));memset(msg->msg.goods, 0, sizeof(msg->msg.goods));char sql[1024];char *errmsg = NULL;char **result = NULL;int rows, columns;// 创建 SQL 查询sprintf(sql, "select * from  Express_information where send_tel = %ld;", msg->msg.send_tel);// 执行 SQL 查询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 send_kuaidi(head *msg) // 送快递
{memset(msg->buf, 0, sizeof(msg->buf));printf("%ld\n", msg->msg.order);char sql[1024];char *errmsg = NULL;char **result = NULL;int hang, lie;time_t t;struct tm *tm;time(&t);tm = localtime(&t);while (1){snprintf(sql, sizeof(sql), "update  Express_information set status=1 where order_n=%ld;", msg->msg.order);if (sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK){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 Cancel_the_order(head *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 Express_information where order_n=%ld;", msg->msg.order);snprintf(sql1, sizeof(sql1), "update lishijilu set rtime='%s' where order_n=%ld;", rtime, msg->msg.order);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 history(head *msg) // 查看历史记录
{char sql[1100];char *errmsg = NULL;char **result = NULL;int hang, lie;while (1){if (strcmp(msg->buf, "all") == 0){sprintf(sql, "select * from lishijilu;");memset(msg->buf, 0, sizeof(msg->buf));}else{sprintf(sql, "select * from lishijilu where stime='%s';", msg->buf);memset(msg->buf, 0, sizeof(msg->buf));}int rc = sqlite3_get_table(db, sql, &result, &hang, &lie, &errmsg);if (rc != 0){sprintf(msg->buf, "查询历史记录失败: %s", errmsg);break;}else{if (hang > 0){for (int i = 1; i <= hang; ++i){strcat(msg->buf, "查询到的信息:");for (int j = 0; j < lie; ++j){strcat(msg->buf, result[i * lie + j]);strcat(msg->buf, " ");}strcat(msg->buf, "\n");}break;}else{strcpy(msg->buf, "该历史记录不存在.");break;}}}send(msg->fd, msg->buf, strlen(msg->buf) - 1, 0);
}int main(int argc, char const *argv[])
{char buf[256];if (argc != 2){printf("输入错误\n");return -1;}int sockfd = socket(AF_INET, SOCK_STREAM, 0);if (sockfd < 0){perror("socket 失败");return -1;}printf("socket 成功\n");int flag = 1;setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag)); // 设置地址重用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 失败");return -1;}printf("bind 成功\n");if (listen(sockfd, 7) < 0){perror("listen 失败");return -1;}printf("正在监听 端口号为%d\n", ntohs(saddr.sin_port));// 创建或打开数据库if (sqlite3_open("./msg.db", &db) != 0){printf("打开或创建数据库失败:%s", sqlite3_errmsg(db));return -1;}printf("打开数据库成功\n");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 Express_information(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(&readfd);FD_ZERO(&tempfd);FD_SET(sockfd, &readfd);int max = sockfd;while (1){tempfd = readfd;int ret = select(max + 1, &tempfd, NULL, NULL, NULL);if (ret < 0){perror("select 失败");return -1;}if (FD_ISSET(sockfd, &tempfd)){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;FD_SET(acceptfd, &readfd);if (max < acceptfd){max = acceptfd;}}for (int i = sockfd + 1; i <= max; i++){if (FD_ISSET(i, &tempfd)){int rev = recv(i, &msg, sizeof(msg), 0);msg.fd = i;if (rev < 0){perror("recv失败");return -1;}else if (rev == 0){printf("%s退出\n", inet_ntoa(caddr.sin_addr));FD_CLR(i, &readfd);close(i);while (!FD_ISSET(max, &readfd)){max--;}}else{printf("%s:%c\n", msg.name, msg.type);switch (msg.type){case 'R':Register(&msg); // 注册break;case 'L':login(&msg); // 登录break;case 'D':cancel(&msg); // 注销break;case 'U':Modify_user_password(&msg); // 修改用户密码break;case 'A':Order_status_inquiry(&msg); // 订单状态查询break;case 'F':Check_courie(&msg); // 查快递break;case 'S':Send_an_express_deliver(&msg); // 寄快递break;case 'E':send_kuaidi(&msg); // 送快递break;case 'P':Modify_courier_information(&msg); // 修改快递信息break;case 'H':history(&msg);break;case 'C':Cancel_the_order(&msg); // 取消订单break;}}}}}return 0;
}

四:用户客户端代码实现:

#include "head.h"head msg;
int flag = 0; // 初始标志位设为登录登录状态// 登录界面
void init()
{printf("...R:注册...\n");printf("...L:登录...\n");printf("...D:注销...\n");
}void kuaidi()
{printf("....F:查快递...\n");printf("...S:寄快递...\n");printf("...C:取消订单...\n");printf("...U:修改用户信息..\n");printf("...P:修改快递信息...\n");printf("...Q:返回一级菜单..\n");
}void Register(head *msg) // 注册
{memset(msg->name, 0, sizeof(msg->name));memset(msg->password, 0, sizeof(msg->password));printf("用户名:");scanf("%s", msg->name);getchar();printf("用户密码:");scanf("%s", msg->password);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 login(head *msg) // 登录
{while (1){memset(msg->name, 0, sizeof(msg->name));memset(msg->password, 0, sizeof(msg->password));printf("请输入用户名:");scanf("%s", msg->name);getchar();printf("请输入用户密码:");scanf("%s", msg->password);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 = 1;break;}if (strcmp(msg->buf, "登录失败") == 0){continue;}}
}
void Send_an_express_delivery(head *msg) // 寄快递
{memset(msg->msg.sender, 0, sizeof(msg->msg.sender));memset(msg->msg.send_addr, 0, sizeof(msg->msg.send_addr));memset(msg->msg.reciver, 0, sizeof(msg->msg.reciver));memset(msg->msg.recive_addr, 0, sizeof(msg->msg.recive_addr));memset(msg->msg.goods, 0, sizeof(msg->msg.goods));printf("发件人姓名,地址,电话:");scanf("%s %s %ld", msg->msg.sender, msg->msg.send_addr, &msg->msg.send_tel);getchar();printf("收件人姓名,地址,电话:");scanf("%s %s %ld", msg->msg.reciver, msg->msg.recive_addr, &msg->msg.recive_tel);getchar();printf("货物重量,名称:");scanf("%f %s", &msg->msg.weight, msg->msg.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 Check_courie(head *msg) // 查快递
{printf("发件人电话:");scanf("%ld", &msg->msg.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 Modify_courier_information(head *msg) // 修改快递信息
{char leixing[100];printf("请输入要修改的快递单号:");scanf("%ld", &msg->msg.order);getchar();while (1){printf("请输入要修改的内容(发送人s,发送地址s1,发送人电话S2,收件人R,收件地址R1,收件人电话R2,货物重量W,货物名称G):");scanf("%s", leixing);getchar();if (strcmp(leixing, "发送人") == 0){memset(msg->msg.sender, 0, sizeof(msg->msg.sender));printf("请输入要修改的信息:");scanf("%s", msg->msg.sender);getchar();printf("%s\n", msg->msg.sender);strcpy(msg->buf, "发送人");break;}else if (strcmp(leixing, "发送地址") == 0){memset(msg->msg.send_addr, 0, sizeof(msg->msg.send_addr));printf("请输入要修改的信息:");scanf(" %s", msg->msg.send_addr);strcpy(msg->buf, "发送地址");break;}else if (strcmp(leixing, "发送人电话") == 0){printf("请输入要修改的信息:");scanf(" %ld", &msg->msg.send_tel);strcpy(msg->buf, "发送人电话");break;}else if (strcmp(leixing, "收件人") == 0){memset(msg->msg.reciver, 0, sizeof(msg->msg.reciver));printf("请输入要修改的信息:");scanf(" %s", msg->msg.reciver);strcpy(msg->buf, "收件人");break;}else if (strcmp(leixing, "收件地址") == 0){memset(msg->msg.recive_addr, 0, sizeof(msg->msg.recive_addr));printf("请输入要修改的信息:");scanf(" %s", msg->msg.recive_addr);strcpy(msg->buf, "收件地址");break;}else if (strcmp(leixing, "收件人电话") == 0){printf("请输入要修改的信息:");scanf(" %ld", &msg->msg.recive_tel);strcpy(msg->buf, "收件人电话");break;}else if (strcmp(leixing, "货物重量") == 0){printf("请输入要修改的信息:");scanf(" %f", &msg->msg.weight);strcpy(msg->buf, "货物重量");break;}else if (strcmp(leixing, "货物名称") == 0){memset(msg->msg.goods, 0, sizeof(msg->msg.goods));printf("请输入要修改的信息:");scanf(" %s", msg->msg.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 Cancel_the_order(head *msg) // 取消订单
{printf("请输入要取消的快递单号:");scanf("%ld", &msg->msg.order);getchar();send(msg->fd, msg, sizeof(*msg), 0);recv(msg->fd, msg->buf, sizeof(msg->buf), 0);printf("%s\n", msg->buf);
}void Modify_user_password(head *msg) // 修改用户密码
{memset(msg->password, 0, sizeof(msg->password));printf("请输入要修改后的密码:");scanf("%s", msg->password);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 cancel(head *msg) // 注销
{memset(msg->name, 0, sizeof(msg->name));memset(msg->password, 0, sizeof(msg->password));printf("请输入你要注销的用户名:");scanf("%s", msg->name);getchar();printf("请输入用户密码:");scanf("%s", msg->password);getchar();send(msg->fd, msg, sizeof(*msg), 0);recv(msg->fd, msg->buf, sizeof(msg->buf), 0);printf("%s\n", msg->buf);
}int main(int argc, char const *argv[])
{int sockfd = socket(AF_INET, SOCK_STREAM, 0);if (sockfd < 0){perror("socket err\n");return -1;}struct sockaddr_in addr;addr.sin_family = AF_INET;addr.sin_port = htons(atoi(argv[1]));addr.sin_addr.s_addr = inet_addr("192.168.153.152");socklen_t addrlen = sizeof(addr);// 3.请求连接if (connect(sockfd, (struct sockaddr *)&addr, addrlen) < 0){perror("connect err");return -1;}printf("connect 成功\n");// 循环while (1){memset(msg.buf, 0, sizeof(msg.buf));msg.usertype = 1;msg.fd = sockfd; // 用于连接if (flag == 0){// 调函数init();}if (flag == 1){// 同上步kuaidi();}printf("请输入:");scanf(" %c", &msg.type);printf("msg.type:%c\n", msg.type);switch (msg.type){case 'R':Register(&msg); // 注册break;case 'L':login(&msg); // 登录break;case 'S':Send_an_express_delivery(&msg); // 寄快递break;case 'F':Check_courie(&msg); // 查快递break;case 'P':Modify_courier_information(&msg); // 修改快递信息break;case 'C':Cancel_the_order(&msg); // 取消订单break;case 'U':Modify_user_password(&msg); // 修改用户密码break;case 'D':cancel(&msg); // 注销break;case 'Q':flag = 0; // 返回登录菜单break;default:break;}}// 6.关闭close(sockfd);return 0;
}

五:快递员客户端实现:

#include "head.h"head msg;
int flag = 0;void denglujiemian();                   // 登录界面
void kuaidijiemian();                   // 快递界面
void zhuce(head *msg);                  // 注册
void denglu(head *msg);                 // 登录
void xiugaiyonghumima(head *msg);       // 修改用户密码
void songkuaidi(head *msg);             // 送快递
void dingdanzhuangtaichaxun(head *msg); // 订单状态查询
void chakanlishijilu(head *msg);        // 查看历史记录
void zhuxiao(head *msg);                // 注销int main(int argc, char const *argv[])
{// 1.创建流式套接字int sockfd = socket(AF_INET, SOCK_STREAM, 0);if (sockfd < 0){perror("socket err");return -1;}// 2.填充结构体struct sockaddr_in saddr;saddr.sin_family = AF_INET;saddr.sin_port = htons(atoi(argv[1]));saddr.sin_addr.s_addr = inet_addr("192.168.153.152");socklen_t addrlen = sizeof(saddr);// 3.请求连接if (connect(sockfd, (struct sockaddr *)&saddr, addrlen) < 0){perror("connect err");return -1;}printf("connect 成功\n");while (1){memset(msg.buf, 0, sizeof(msg.buf));msg.usertype = 2;msg.fd = sockfd;if (flag == 0){denglujiemian(); // 登录界面}if (flag == 1){kuaidijiemian(); // 快递界面}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 'A':dingdanzhuangtaichaxun(&msg); // 订单状态查询break;case 'E':songkuaidi(&msg); // 送快递break;case 'H':chakanlishijilu(&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 denglujiemian() // 登录界面
{printf("...R:注册..\n");printf("...L:登录...\n");printf("...D:注销..\n");
}
void kuaidijiemian() // 快递界面
{printf("..A:查快递..\n");printf("*..E:送快递.. \n");printf("..U:修改用户信息..\n");printf("..H:查询历史记录..\n");printf("...Q:返回一级菜单...\n");
}
void zhuce(head *msg) // 注册
{memset(msg->name, 0, sizeof(msg->name));memset(msg->password, 0, sizeof(msg->password));printf("请输入用户名:");scanf("%s", msg->name);getchar();printf("请输入用户密码:");scanf("%s", msg->password);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(head *msg) // 登录
{while (1){memset(msg->name, 0, sizeof(msg->name));memset(msg->password, 0, sizeof(msg->password));printf("请输入用户名:");scanf("%s", msg->name);getchar();printf("请输入用户密码:");scanf("%s", msg->password);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 = 1;break;}if (strcmp(msg->buf, "登录失败") == 0){continue;}}
}
void xiugaiyonghumima(head *msg) // 修改用户密码
{memset(msg->password, 0, sizeof(msg->password));printf("请输入要修改后的密码:");scanf("%s", msg->password);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(head *msg) // 注销
{memset(msg->name, 0, sizeof(msg->name));memset(msg->password, 0, sizeof(msg->password));printf("请输入你要注销的用户名:");scanf("%s", msg->name);getchar();printf("请输入用户密码:");scanf("%s", msg->password);getchar();send(msg->fd, msg, sizeof(*msg), 0);recv(msg->fd, msg->buf, sizeof(msg->buf), 0);printf("%s\n", msg->buf);
}
void songkuaidi(head *msg) // 送快递
{printf("请输入要送达的快递单号:");scanf("%ld", &msg->msg.order);getchar();send(msg->fd, msg, sizeof(*msg), 0);recv(msg->fd, msg->buf, sizeof(msg->buf), 0);printf("%s\n", msg->buf);
}
void dingdanzhuangtaichaxun(head *msg) // 订单状态查询
{printf("请输入要查询订单的状态(0未送达,1已送达):");scanf("%d", &msg->msg.status);getchar();send(msg->fd, msg, sizeof(*msg), 0);recv(msg->fd, msg->buf, sizeof(msg->buf), 0);printf("%s\n", msg->buf);
}
void chakanlishijilu(head *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->fd, msg, sizeof(*msg), 0);memset(msg->buf, 0, sizeof(msg->buf));recv(msg->fd, msg->buf, sizeof(msg->buf), 0);break;}else if (strcmp(leixing, "time") == 0){printf("请输入要查询的时间:");scanf("%s", msg->buf);getchar();send(msg->fd, msg, sizeof(*msg), 0);memset(msg->buf, 0, sizeof(msg->buf));recv(msg->fd, msg->buf, sizeof(msg->buf), 0);break;}else{printf("输入错误,请重新输入\n");continue;}}printf("%s\n", msg->buf);
}

六:视频链接 

爱哭的小粘豆包:https://www.bilibili.com/video/BV1fSDrY7EMN/?spm_id_from=333.999.0.0 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/475979.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

241120学习日志——[CSDIY] [InternStudio] 大模型训练营 [09]

CSDIY&#xff1a;这是一个非科班学生的努力之路&#xff0c;从今天开始这个系列会长期更新&#xff0c;&#xff08;最好做到日更&#xff09;&#xff0c;我会慢慢把自己目前对CS的努力逐一上传&#xff0c;帮助那些和我一样有着梦想的玩家取得胜利&#xff01;&#xff01;&…

PCB 间接雷击模拟

雷击是一种危险的静电放电事件&#xff0c;其中两个带电区域会瞬间释放高达 1 千兆焦耳的能量。雷击就像一个短暂而巨大的电流脉冲&#xff0c;会对建筑物和电子设备造成严重损坏。雷击可分为直接和间接两类&#xff0c;其中间接影响是由于感应能量耦合到靠近雷击位置的物体。间…

IDEA2019搭建Springboot项目基于java1.8 解决Spring Initializr无法创建jdk1.8项目 注释乱码

后端界面搭建 将 https://start.spring.io/ 替换https://start.aliyun.com/ 报错 打开设置 修改如下在这里插入代码片 按此方法无果 翻阅治疗后得知 IDEA2019无法按照网上教程修改此问题因此更新最新idea2024或利用插件Alibaba Clouod Toolkit 换用IDEA2024创建项目 下一步…

单向C to DP视频传输解决方案 | LDR6500

LDR6500D如何通过Type-C接口实现手机到DP接口的单向视频传输 在当今数字化浪潮中&#xff0c;投屏技术作为连接设备、共享视觉内容的桥梁&#xff0c;其重要性日益凸显。PD&#xff08;Power Delivery&#xff09;芯片&#xff0c;特别是集成了Type-C接口与DisplayPort&#xf…

Leetcode 第 143 场双周赛题解

Leetcode 第 143 场双周赛题解 Leetcode 第 143 场双周赛题解题目1&#xff1a;3345. 最小可整除数位乘积 I思路代码复杂度分析 题目2&#xff1a;3346. 执行操作后元素的最高频率 I思路代码复杂度分析 题目3&#xff1a;3347. 执行操作后元素的最高频率 II题目4&#xff1a;33…

Spark 之 Aggregate

Aggregate 参考链接&#xff1a; https://github.com/PZXWHU/SparkSQL-Kernel-Profiling 完整的聚合查询的关键字包括 group by、 cube、 grouping sets 和 rollup 4 种 。 分组语句 group by 后面可以是一个或多个分组表达式&#xff08; groupingExpressions &#xff09;…

【IDEA】解决总是自动导入全部类(.*)问题

文章目录 问题描述解决方法 我是一名立志把细节说清楚的博主&#xff0c;欢迎【关注】&#x1f389; ~ 原创不易&#xff0c; 如果有帮助 &#xff0c;记得【点赞】【收藏】 哦~ ❥(^_-)~ 如有错误、疑惑&#xff0c;欢迎【评论】指正探讨&#xff0c;我会尽可能第一时间回复…

如何快速将Excel数据导入到SQL Server数据库

工作中&#xff0c;我们经常需要将Excel数据导入到数据库&#xff0c;但是对于数据库小白来说&#xff0c;这可能并非易事&#xff1b;对于数据库专家来说&#xff0c;这又可能非常繁琐。 这篇文章将介绍如何帮助您快速的将Excel数据导入到sql server数据库。 准备工作 这里&…

在centos7中安装SqlDeveloper的Oracle可视化工具

1.下载安装包 &#xff08;1&#xff09;在SqlDeveloper官网下载&#xff08;Oracle SQL Developer Release 19.2 - Get Started&#xff09;对应版本的安装包即可&#xff08;安装包和安装命令如下&#xff09;&#xff1a; &#xff08;2&#xff09;执行完上述命令后&#x…

【动手学深度学习Pytorch】4. 神经网络基础

模型构造 回顾一下感知机。 nn.Sequential()&#xff1a;定义了一种特殊的module。 torch.rand()&#xff1a;用于生成具有均匀分布的随机数&#xff0c;这些随机数的范围在[0, 1)之间。它接受一个形状参数&#xff08;shape&#xff09;&#xff0c;返回一个指定形状的张量&am…

Spring Boot + Vue 基于 RSA 的用户身份认证加密机制实现

Spring Boot Vue 基于 RSA 的用户身份认证加密机制实现 什么是RSA&#xff1f;安全需求介绍前后端交互流程前端使用 RSA 加密密码安装 jsencrypt库实现敏感信息加密 服务器端生成RSA的公私钥文件Windows环境 生成rsa的公私钥文件Linux环境 生成rsa的公私钥文件 后端代码实现返…

一键部署 200+ 开源软件的 Websoft9 面板,Github 2k+ 星星

Websoft9面板是一款基于Web的PaaS/Linux面板&#xff0c;可用于在自己的服务器上一键部署200多种热门开源应用&#xff0c;在Github上获得了2k星星。 特点与优势 丰富的开源软件集成&#xff1a;涵盖数据库、Web服务器、企业建站、电商系统、教育系统、中间件、大数据工具等多…

NLP论文速读(MPO)|通过混合偏好优化提高多模态大型语言模型的推理能力

论文速读|Dynamic Rewarding with Prompt Optimization Enables Tuning-free Self-Alignment of Language Models 论文信息&#xff1a; 简介&#xff1a; 本文探讨的背景是多模态大型语言模型&#xff08;MLLMs&#xff09;在多模态推理能力上的局限性&#xff0c;尤其是在链式…

动态规划子数组系列一>等差数列划分

题目&#xff1a; 解析&#xff1a; 代码&#xff1a; public int numberOfArithmeticSlices(int[] nums) {int n nums.length;int[] dp new int[n];int ret 0;for(int i 2; i < n; i){dp[i] nums[i] - nums[i-1] nums[i-1] - nums[i-2] ? dp[i-1]1 : 0;ret dp[i…

用 React18 构建Tic-Tac-Toe(井字棋)游戏

下面是一个完整的 Tic-Tac-Toe&#xff08;井字棋&#xff09;游戏的实现&#xff0c;用 React 构建。包括核心逻辑和组件分离&#xff0c;支持两人对战。 1. 初始化 React 项目&#xff1a; npx create-react-app tic-tac-toe cd tic-tac-toe2.文件结构 src/ ├── App.js…

前端—Cursor编辑器

在当今快速发展的软件开发领域&#xff0c;效率和质量是衡量一个工具是否优秀的两个关键指标。今天&#xff0c;我要向大家推荐一款革命性的代码编辑器——Cursor&#xff0c;它集成了强大的AI功能&#xff0c;旨在提高开发者的编程效率。以下是Cursor编辑器的详细介绍和推荐理…

uniapp页面样式和布局和nvue教程详解

uniapp页面样式和布局和nvue教程 尺寸单位 uni-app 支持的通用 css 单位包括 px、rpx px 即屏幕像素。rpx 即响应式px&#xff0c;一种根据屏幕宽度自适应的动态单位。以750宽的屏幕为基准&#xff0c;750rpx恰好为屏幕宽度。屏幕变宽&#xff0c;rpx 实际显示效果会等比放大…

Kubernetes 安装配置ingress controller

> 对于Kubernetes的Service&#xff0c;无论是Cluster-Ip和NodePort均是四层的负载&#xff0c;集群内的服务如何实现七层的负载均衡&#xff0c;这就需要借助于Ingress&#xff0c;Ingress控制器的实现方式有很多&#xff0c;比如nginx, Contour, Haproxy, trafik, Istio。…

js批量输入地址获取经纬度

使用js调用高德地图的接口批量输入地址获取经纬度。 以下的请求接口的key请换成你的key。 创建key&#xff1a;我的应用 | 高德控制台 &#xff0c;服务平台选择《Web服务》。 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-…

天润融通携手挚达科技:AI技术重塑客户服务体验

业务爆发式增长&#xff0c;但座席服务却跟不上&#xff0c;怎么办&#xff1f; 智能充电领导者的挚达科技就面临过 这样的问题&#xff0c;让我们来看看如何解决。 2010年以来&#xff0c;国内新能源汽车市场进入高速发展期&#xff0c;作为新能源汽车的重要配件&#xff0c…