当前位置: 首页 > news >正文

11.1 网络编程-套接字

练习: 使用搭建好的服务器和客户端,实现一个完整的注册,登录功能
                服务器使用链表 + 文件IO的形式去记录账号和密码

代码实现:

服务器端:
#include <myhead.h>
struct Pack{char flags;char name[20];char pswd[20];
};
//创建单链表结构体类型
typedef struct node{union{int len;struct Pack data;};struct node *next;
}Link,* Plink;
Plink L;
//创建链表表头
Plink create_link(){Plink p=(Plink)malloc(sizeof(Link));if(p==NULL){perror("malloc");return NULL;}p->len=0;p->next=NULL;return p;
}
//采用尾插法增加注册信息
int insert_tail(Plink L,struct Pack *Pdata){//创建新节点Plink p=(Plink)malloc(sizeof(Link));if(p==NULL){perror("malloc");return -1;}p->data=*Pdata;//接收数据Plink t=L;while(t->next!=NULL){//遍历到尾部t=t->next;}p->next=t->next;t->next=p;L->len++;return 1;
}
//查找登录信息
int research_link(Plink L,struct Pack *Pdata){Plink t=L->next;while(t!=NULL){if(strcmp(t->data.name,Pdata->name)==0&&\strcmp(t->data.pswd,Pdata->pswd)==0){return 1;}t=t->next;}return -1;
}
void handler(int signo){if(signo==SIGINT){FILE *fp=fopen("./server.txt","a+");if(fp==NULL){perror("fopen");return;}Plink t=L->next;while(t!=NULL){fprintf(fp,"%s %s\n",t->data.name,t->data.pswd);t=t->next;}fclose(fp);exit(EXIT_SUCCESS);}
}
int main(int argc, const char *argv[])
{//当服务器断线时,将链表信息存储到文件中保存if(signal(SIGINT,handler)==SIG_ERR){perror("signal");return -1;}if(argc!=2){printf("请输入端口号\n");return -1;}	int port=atoi(argv[1]);//从终端接收端口号//创建tcp套接字int server=socket(AF_INET,SOCK_STREAM,0);//准备一个tcp用的地址信息结构体,用于存放ip和portaddr_in_t addr={0};addr.sin_family=AF_INET;addr.sin_port=htons(port);//端口号转为网络字节序addr.sin_addr.s_addr=inet_addr("127.0.0.1");//用于测试案例使用//使用已经准备好的地址信息结构体,为套接字绑定ip和portif(bind(server,(addr_t *)&addr,sizeof(addr))==-1){//因为端口号容易被占用,所以bind会容易出错,需要判断perror("bind error");return -1;}//监听listen(server,10);addr_in_t client_addr={0};socklen_t client_len=sizeof(addr);int client=accept(server,(addr_t *)&client_addr,&client_len);printf("客户端连接成功\n");//服务器读取消息/*int flags=fcntl(client,F_GETFL);flags=flags|0_NONBLOCK;fcntl(client,F_SETFL,flags);*/struct Pack pack={0};L=create_link();//创建链表表头while(1){memset(&pack,0,sizeof(pack));int res=read(client,&pack,sizeof(pack));if(res==0){	printf("客户端断开连接\n");close(client);		raise(SIGINT);//当客户端断开连接时,向自己进程发送信号break;}if(pack.flags==1){//链表增加注册信息采用尾插法char flag1;if(insert_tail(L,&pack)==1){printf("注册信息已加载\n");flag1=1;write(client,&flag1,1);//往客户端回复已注册成功消息}else{printf("注册错误,无法加载\n");flag1=0;write(client,&flag1,1);//往客户端回复注册失败消息}}else if(pack.flags==2){//遍历链表已查找登录信息char flag2;if(research_link(L,&pack)==1){printf("与服务器注册信息匹配\n");flag2=1;write(client,&flag2,1);//往客户端回复登录成功消息}else{printf("与服务器注册信息不匹配\n");flag2=0;write(client,&flag2,1);//往客户端回复登录失败消息}}}return 0;
}
客户端端 :
#include <myhead.h> 
struct Pack{char flags;char name[20];char pswd[20];
};
void menu(){printf("****用户注册登录功能****\n");printf("****1.注册**2.登录******\n");printf("*********0.退出*********\n");
}
void logic_user(struct Pack *ps,int client){printf("请输入注册姓名:");scanf("%s",ps->name);printf("请输入注册密码:");scanf("%s",ps->pswd);write(client,ps,sizeof(struct Pack));printf("注册信息已发送\n");
}
void pswd_user(struct Pack *ps,int client){printf("请输入登录姓名:");scanf("%s",ps->name);printf("请输入登录密码:");scanf("%s",ps->pswd);write(client,ps,sizeof(struct Pack));printf("登录信息已发送\n");
}
int main(int argc, const char *argv[])    
{                                         if(argc!=2){printf("请输入端口号\n");return -1;}int port=atoi(argv[1]);//从终端接收端口号//创建tcp套接字int client=socket(AF_INET,SOCK_STREAM,0);//准备一个tcp用的地址信息结构体,用于存放ip和portaddr_in_t addr={0};addr.sin_family=AF_INET;addr.sin_port=htons(port);//端口号转为网络字节序addr.sin_addr.s_addr=inet_addr("127.0.0.1");//与服务器连接if(connect(client,(addr_t *)&addr,sizeof(addr))==-1){perror("connect error");return -1;}struct Pack pack={0};//向客户端发送消息while(1){menu();char res=0;memset(&pack,0,sizeof(pack));printf("请输入选项:");scanf("%d",&pack.flags);switch(pack.flags){case 1:logic_user(&pack,client);read(client,&res,1);//从服务器读取注册完成信号if(res==1){printf("注册成功\n");}else{printf("注册失败\n");}break;case 2:pswd_user(&pack,client);read(client,&res,1);//从服务器读取登录完成信号if(res==1){printf("登录成功\n");}else{printf("登录失败\n");}break;case 0:exit(EXIT_SUCCESS);default:printf("输入选项错误,请重新输入\n");break;}	}return 0;                             
}          
 实现结果:


http://www.mrgr.cn/news/65010.html

相关文章:

  • 基于Python的乡村居民信息管理系统【附源码】
  • 推荐一款高级的安装程序打包工具:Advanced Installer Architect
  • Docker部署Portainer CE结合内网穿透实现容器的可视化管理与远程访问
  • 苹果安装python环境
  • 如何卸载电脑上的软件?彻底删除第三方和系统自带软件方法!(新款)
  • 天生倔强脸的白纸新人,徐畅演艺生涯初舞台获得肯定!
  • C语言-详细讲解-洛谷P1909 [NOIP2016 普及组] 买铅笔
  • 【数据结构】二叉树——层序遍历
  • Python Matplotlib 如何处理大数据集的绘制,提高绘图效率
  • 上尚优选项目
  • interrupt、interrupted、isInterrupted方法详解
  • WPF+MVVM案例实战(二十一)- 制作一个侧边弹窗栏(CD类)
  • LeetCode 0685.冗余连接 II:并查集(和I有何不同分析)——详细题解(附图)
  • Docker容器消耗资源过多导致宿主机死机解决方案
  • 发现不为人知的AI宝藏:深藏功与名! —— 《第十期》
  • js逆向-模拟加密
  • Linux的IP网路命令: 用于显示和操作网络接口(网络设备)的命令ip link详解
  • masm汇编字符串输出演示
  • ChatGPT 和 RAG(检索增强生成)的区别;ChatGPT 和 RAG 的联系
  • AIGC对传统内容创作行业的冲击
  • 【Linux】make/makefile/gdb调试技巧/进度条小程序
  • 无人机场景 - 目标检测数据集 - 夜间车辆检测数据集下载「包含VOC、COCO、YOLO三种格式」
  • 【蓝队技能】【溯源反制】反打红队-蜜罐工具反制
  • SpringBoot集成ELK收集日志管理
  • PyQt5入门级超详细教程中篇
  • 【论文笔记】Dense Connector for MLLMs