2024.4.21

 网络聊天室-------服务器端

#include "head.h"
#define SER_IP "192.168.125.100"
#define SER_PORT 8888
int main(int argc, const char *argv[])
{//1.创建结构体int sfd=socket(AF_INET,SOCK_DGRAM,0);if(sfd==-1){perror("socket");return -1;}printf("socket success\n");//2.设置端口号快速重启int reuse=1;if(setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse))==-1){perror("setsockopt");return -1;}printf("setsockopt success\n");//3.绑定IP和端口号struct sockaddr_in sin;sin.sin_family=AF_INET;sin.sin_port=htons(SER_PORT);sin.sin_addr.s_addr=inet_addr(SER_IP);if(bind(sfd,(struct sockaddr*)&sin,sizeof(sin))==-1){perror("bind");return -1;}printf("bind success\n");//4.数据交互struct sockaddr_in cin;            //客户端发送过来的地址socklen_t cinlen=sizeof(cin);char cbuf[255];//创建用户地址结构体int maxi=0;struct sockaddr_in rin[100]; //创建用户地址结构体数组//创建用户信息结构体Msg_t* H=Head_creat();   //创建头结点//IO多路复用struct pollfd pfds[2];pfds[0].fd=0;pfds[0].events=POLLIN;pfds[1].fd=sfd;pfds[1].events=POLLIN;char name[20];char passwd[20];while(1){int res=poll(pfds,2,-1);if(res==0){printf("timr out\n");return 0;}if(res==-1){perror("poll");return -1;}//执行到此处说明接发信息被触发if(pfds[1].revents==POLLIN){bzero(cbuf,sizeof(cbuf));recvfrom(sfd,cbuf,sizeof(cbuf),0,(struct sockaddr*)&cin,&cinlen);char* p1=cbuf;char cfs[211]="";strcpy(cfs,p1+41);//	printf("cbuf:%s\ncfs:%s\n",p1+41,cfs);if(cbuf[0]=='Z'){                                   //表示用户注册bzero(name,sizeof(name));bzero(passwd,sizeof(passwd));char* p1=cbuf;strncpy(name,p1+1,20);strncpy(passwd,p1+21,20);//printf("注册用户信息%s||%s\n",name,passwd);     //*********测试用//if(find_node(H,name,passwd)==0){ //如果用户列表不存在则允许创建tail_inst(H,name,passwd);        //用户信息存入链表bzero(cbuf,sizeof(cbuf));cbuf[0]='Y';strcpy(p1+41,"注册成功,欢迎登录聊天系统"); //将成功信息返回客户端//	printf("rin[maxi].sin_port=%hd ,rin[maxi].sin_addr.s_addr=%s\n",ntohs(rin[maxi-1].sin_port),inet_ntoa(rin[maxi-1].sin_addr));//	printf("cin.sin_port=%hd ,cin.sin_addr.s_addr=%s\n",ntohs(cin.sin_port),inet_ntoa(cin.sin_addr));sendto(sfd,cbuf,sizeof(cbuf),0,(struct sockaddr*)&cin,sizeof(cin));}else if(find_node(H,name,passwd)!=0){     //用户已存在并通知客户端bzero(cbuf,sizeof(cbuf));cbuf[0]='N';strcpy(p1+41,"用户已存在,请重新输入");   //将失败信息返回客户端sendto(sfd,cbuf,sizeof(cbuf),0,(struct sockaddr*)&cin,sizeof(cin));}}else if(cbuf[0]=='L'){                                 //表示用户登录bzero(name,sizeof(name));bzero(passwd,sizeof(passwd));char* p1=cbuf;strncpy(name,p1+1,20);strncpy(passwd,p1+21,20);int res=find_node(H,name,passwd);if(res==1){if(maxi>1024){  //判断登录用户是否过载cbuf[0]='N';strcpy(p1+41,"登录用户已满,请等待后重试\n");sendto(sfd,cbuf,sizeof(cbuf),0,(struct sockaddr*)&cin,sizeof(cin));break;}rin[maxi]=cin;    //*************************将登录信息存入注册数组中maxi++;/*	int i=0;while(1){if(rin[i].sin_addr.s_addr=='\0'){rin[i]=cin;break;}i++;   //最小未使用找出i}if(maxi<i){maxi=i;  //留下最大已使用的下标printf("maxi=%d\n",maxi);  ********测试用(暂时弃用)}*/printf("%s:已登录\n",name);                   //给服务端发送提示cbuf[0]='Y';strcpy(p1+41,"已登录");          //将上线信息发送给所有用户for(int j=0;j<maxi;j++){sendto(sfd,cbuf,sizeof(cbuf),0,(struct sockaddr*)&rin[j],sizeof(rin[j]));}}else if(res==2){  //密码错误,用户重新输入cbuf[0]='N';strcpy(p1+41,"密码错误,请重试\n");sendto(sfd,cbuf,sizeof(cbuf),0,(struct sockaddr*)&cin,sizeof(cin));}else if(res==0){cbuf[0]='N';strcpy(p1+41,"暂无该用户,请注册\n");sendto(sfd,cbuf,sizeof(cbuf),0,(struct sockaddr*)&cin,sizeof(cin));}}else if(cbuf[0]=='C'){                               //表示用户聊天char* p1=cbuf;bzero(name,sizeof(name));cbuf[0]='Y';strncpy(name,p1+1,20);for(int j=0;j<maxi;j++){sendto(sfd,cbuf,sizeof(cbuf),0,(struct sockaddr*)&rin[j],sizeof(rin[j]));printf("rin[%d].sin_port=%d ,rin[maxi].sin_addr.s_addr=%s\n",j,ntohs(rin[j].sin_port),inet_ntoa(rin[j].sin_addr));//printf("cin.sin_port=%d ,cin.sin_addr.s_addr=%s\n",ntohs(cin.sin_port),inet_ntoa(cin.sin_addr));}printf("用户%s信息发送成功\n",name);}else if(cbuf[0]=='Q'){                                //表示用户退出cbuf[0]='Y';char* p1=cbuf;strcpy(p1+41,"已下线");  //定义结构体rin[n],将下线信息发送给其他客户 for(int j=0;j<=maxi;j++){sendto(sfd,cbuf,sizeof(cbuf),0,(struct sockaddr*)&rin[j],sizeof(rin[j]));}}printf("ss:%s\n",cbuf);}if(pfds[0].revents==POLLIN){  //向所有客户端发送通知bzero(cbuf,sizeof(cbuf));char* p1=cbuf;char buf[211]="";cbuf[0]='Y';strcpy(p1+1,"Server:");fgets(buf,sizeof(buf),stdin);buf[strlen(buf)-1]='\0';strcpy(p1+41,buf);//	show(H);   //********测试用for(int j=0;j<maxi;j++){sendto(sfd,cbuf,sizeof(cbuf),0,(struct sockaddr*)&rin[j],sizeof(rin[j]));//	printf("rin[%d].sin_port=%d ,rin[maxi].sin_addr.s_addr=%s\n",j,ntohs(rin[maxi-1].sin_port),inet_ntoa(rin[maxi-1].sin_addr));//	printf("客户端说了\n");}}}//5.关闭文件close(sfd);return 0;
}

网络聊天室------结构体部分 

#include "head.h"//创建头结点
Msg_t*  Head_creat(){Msg_t* H=(Msg_t*)malloc(sizeof(Msg_t));if(H==NULL){perror("malloc");return NULL;}H->next=NULL;return H;
}//写入子节点
Msg_t* node_creat(const char* name,const char* passwd){Msg_t* new=(Msg_t*)malloc(sizeof(Msg_t));if(new==NULL){printf("子节点创建有问题\n");return NULL;}new->next=NULL;strcpy(new->name,name);strcpy(new->passwd,passwd);return new;
}//尾插创建子节点
void tail_inst(Msg_t* H,const char* name,const char* passwd){if(H==NULL){printf("入参错误,请检查\n");return;}Msg_t* P=H;while(P->next!=NULL){P=P->next;}Msg_t* new=node_creat(name,passwd);P->next=new;printf("用户%s数据存储成功\n",name);
}//遍历删除子节点
void del_pos_node(Msg_t* H,const char* name){if(H==NULL){printf("入参错误,请检查\n");return;}Msg_t* P=H;while(P->next!=NULL){if(strcmp(P->next->name,name)==0){Msg_t* q=P->next;P->next=q->next;free(q);break;}P=P->next;}printf("用户%s数据删除\n",name);
}
//遍历查询相同子节点
int find_node(Msg_t* H,const char* name,const char* passwd){if(H==NULL){printf("入参错误,请检查\n");return -1;}int num=0;Msg_t* P=H->next;while(P!=NULL){if(strcmp(P->name,name)==0){if(strcmp(passwd,P->passwd)==0){num=1;}else{num=2;}}P=P->next;}
//	printf("num=%d\n",num);  //*********测试用return num;
}void show(Msg_t* H){Msg_t* P=H->next;while(P!=NULL){printf("%s->",P->name);P=P->next;}printf("结束show\n");putchar(10);
}

网路聊天室------客户端 

#include <myinclude.h>
int main(int argc, const char *argv[])
{//1.输入要连接的端口号char ip[30]="";short pt=0;printf("请输入IP地址: ");scanf("%s",ip);while(getchar()!=10);printf("请输入端口号: ");scanf("%hd",&pt);while(getchar()!=10);//2.创建套接字int cfd=socket(AF_INET,SOCK_DGRAM,0);if(cfd==-1){perror("socket");return -1;}printf("socket success\n");//3.设置端口号快速重启int reuse=1;if(setsockopt(cfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse))==-1){perror("socketopt");return -1;}printf("set setsockopt success\n");printf("登陆成功,请稍后\n");sleep(1);//循环执行功能界面//准备变量、结构体struct sockaddr_in cin;socklen_t cinlen=sizeof(cinlen);char cbuf[255];struct sockaddr_in sin;sin.sin_family=AF_INET;sin.sin_port=htons(pt);sin.sin_addr.s_addr=inet_addr(ip);//使用poll完成IO多路复用////数据交互struct pollfd pfd[2];pfd[0].fd=0;pfd[1].fd=cfd;pfd[0].events=POLLIN;pfd[1].events=POLLIN;char name[20];char name1[20];char passwd[20];char buf[211];char cfs[211];char* p1=cbuf;printf("欢迎加入网络聊天室\n");while(1){printf("=======1.登录========\n");printf("=======2.注册========\n");printf("=======0.退出========\n");int num;scanf("%d",&num);while(getchar()!=10);switch(num){    case 1:         //登录、进入聊天界面{bzero(name,sizeof(name));bzero(passwd,sizeof(passwd));bzero(cbuf,sizeof(cbuf));bzero(buf,sizeof(buf));printf("请输入用户名:");scanf("%s",name);strcpy(name1,name);while(getchar()!=10);printf("请输入密码:");scanf("%s",passwd);while(getchar()!=10);cbuf[0]='L';strncpy(p1+1,name,20);strncpy(p1+21,passwd,20);              //将账户密码输入并等待服务端会话sendto(cfd,cbuf,sizeof(cbuf),0,(struct sockaddr*)&sin,sizeof(sin));bzero(cbuf,sizeof(cbuf));recvfrom(cfd,cbuf,sizeof(cbuf),0,NULL,NULL);if(cbuf[0]=='N'){printf("错误:%s\n",p1+41);break;}printf("登陆成功,欢迎\n");while(1){int res=poll(pfd,2,-1);if(res==0){printf("time out\n");return -1;}else if(res==-1){perror("poll");return -1;}                      //poll设立完成char cfs[211]="";if(pfd[0].revents==POLLIN){            //将消息发送给服务器
//*****bzero(cbuf,sizeof(cbuf));bzero(cfs,sizeof(cfs));cbuf[0]='C';strncpy(p1+1,name1,20);
//*****fgets(cfs,sizeof(cfs),stdin);//	printf("cfs:%s\n",cfs);cfs[strlen(cfs)-1]='\0';strcpy(p1+41,cfs);//	printf("cbuf:%s\n",p1+41);if(strcmp(cfs,"quit")==0){bzero(cbuf,sizeof(cbuf));cbuf[0]='Q';strcpy(p1+1,name1);sendto(cfd,cbuf,sizeof(cbuf),0,(struct sockaddr*)&sin,sizeof(sin));close(cfd);goto END;}sendto(cfd,cbuf,sizeof(cbuf),0,(struct sockaddr*)&sin,sizeof(sin));//	printf("发送成功\n");}if(pfd[1].revents==POLLIN){     //将从服务器接收到的信息发送给终端bzero(cbuf,sizeof(cbuf));bzero(name,sizeof(name));bzero(buf,sizeof(buf));recvfrom(cfd,cbuf,sizeof(cbuf),0,NULL,NULL);//char* p1=cbuf;//char name[20]="";strncpy(name,p1+1,20);strncpy(buf,p1+41,211);printf("%s:%s\n",name,buf);//	printf("接收成功\n");                  //***********测试用}}}
END:			break;case 2:     //注册{bzero(name,sizeof(name));bzero(passwd,sizeof(passwd));bzero(cbuf,sizeof(cbuf));printf("请输入注册名:");scanf("%20s",name);while(getchar()!=10);printf("请输入密码:");scanf("%20s",passwd);while(getchar()!=10);cbuf[0]='Z';strncpy(p1+1,name,20);strncpy(p1+21,passwd,20);sendto(cfd,cbuf,sizeof(cbuf),0,(struct sockaddr*)&sin,sizeof(sin));bzero(cbuf,sizeof(cbuf));recvfrom(cfd,cbuf,sizeof(cbuf),0,NULL,NULL);if(cbuf[0]=='N'){printf("错误:%s\n",p1+41);break;}else if(cbuf[0]='Y'){printf("%s\n",p1+41);}}break;case 0:     //退出客户端{printf("已退出聊天系统\n");return 0;}break;}}
}

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

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

相关文章

在Postgres中,如何有效地管理大型数据库的大小和增长

文章目录 一、定期清理和维护1. VACUUM和ANALYZE2. 删除旧数据和归档 二、分区表三、压缩数据四、配置优化1. 调整维护工作负载2. 监控和日志 五、使用外部存储和扩展1. 外部表和FDW2. 扩展和插件 六、定期备份和恢复测试结论 管理大型数据库的大小和增长是数据库管理员&#x…

Java中的变量与常量

标识符 Java语言规定标识符由任意顺序的字母、下划线&#xff08;_&#xff09;、美元符号&#xff08;$&#xff09;和数字组成&#xff0c;并且第一个字符不能是数字。标识符也不能是Java中的关键字&#xff08;保留字&#xff09;。 在Java语言中&#xff0c;标识符的字母…

golang封装发送邮件的代码

golang封装一个发送邮件的代码 golang发送邮件非常简单&#xff0c;下面是一个封装好的代码&#xff0c;只需要把这两个文件放到一个包里&#xff0c;就可以直接使用 email.go package emailimport ("context""github.com/go-playground/validator/v10"…

环境监测系统--------MQ系列气体检测模块驱动教程(保姆级教程)

⏩ 大家好哇&#xff01;我是小光&#xff0c;嵌入式爱好者&#xff0c;一个想要成为系统架构师的大三学生。 ⏩在环境检测中我们经常会用到检测气体的传感器&#xff0c;检测乙醇、甲烷、一氧化碳、氢气等等&#xff0c;博主呕心沥血对MQ系列传感器做一个史上最详细的使用教程…

网络安全产品---堡垒机

what 在网上搜索 运维审计与风险控制系统就是是堡垒机 我认为的堡垒机就是提供高效运维、认证管理、访问控制、安全审计和报表分析功能的云服务设备 实现高效运维的同时最大程度控制运维风险。 how 能够对运维人员维护过程进行全面跟踪、控制、记录、回放 支持细粒度配置…

政企版 WPS Pro 专业版注册安装教程

政企版 WPS Pro 专业版安装及激活步骤 第 1 步&#xff1a;下载压缩包&#xff08;内含注册码&#xff09;【无解压密码】。 第 2 步&#xff1a;解压缩后&#xff0c;运行 exe 文件&#xff0c;默认步骤安装即可。 第 3 步&#xff1a;安装完成后&#xff0c;新建一个 Word …

【AI面试】工作和面试过程中,经常遇到的其他问题汇总二(持续更新)

本篇是延续第一篇:【AI面试】工作和面试过程中,经常遇到的其他问题汇总一(持续更新) 如果你还没有看过上一篇文章,建议先去看看,尽管这两篇文章没有什么交集。 一、在CNN和transformer的训练过程中,学习率的调整,有什么经验? 在训练卷积神经网络(CNN)和Transform…

使用QQ邮箱进行登录验证

使用场景不多说&#xff0c;接下来直接看实现~ 登录到QQ邮箱&#xff0c;进入设置 打开IMAP/SMTP服务&#xff0c;记得把授权码记录下来&#xff0c;后面配置文件中需要用到 新建application的配置文件 spring:mail:# 指定邮件服务器地址host: smtp.qq.comusername: 你自己的q…

ROS 2边学边练(31)-- 管理大工程

前言 往往现实中的工程都是会包含很多节点很多参数很多主题的那种&#xff0c;如果单独通过各种ros2 run命令进行启动管理&#xff0c;恐怕难以招架&#xff0c;主要还是通过launch文件的方式进行管理&#xff0c;而launch文件也可以像节点那样按功能的不同模块化&#xff0c;最…

【学习】黑盒测试用例设计方法都有哪些

在软件测试中&#xff0c;黑盒测试是一种重要的测试方法&#xff0c;它专注于软件的外部行为&#xff0c;而不关心其内部结构和实现。黑盒测试的目标是确保软件的功能符合需求规格说明书中的要求。为了有效地进行黑盒测试&#xff0c;需要设计合理的测试用例。本文将详细介绍黑…

RocketMQ的设计理念和目标

一、设计理念&#xff1a; RocketMQ设计基于主题的发布与订阅模式&#xff0c;其核心功能包括消息发送、消息存储&#xff08;broker&#xff09;、消息消费&#xff0c;整体设计追求简单与性能统一&#xff0c;主要体现在以下三个方面。 1.1、NameServer设计&#xff0c;摒弃…

excel文件预览: luckyexcel+luckysheet

luckyexcel 使用 npm i luckyexcel --saveluckysheet 使用 luckysheet文档 克隆Luckysheet源码到本地 git clone https://github.com/dream-num/Luckysheet.git安装依赖 npm install npm install gulp -g 开发 npm run dev打包 npm run build本地引入 npm run build 后 …

Ansible 连接受控端sudo超时

最近在装Ansible&#xff0c;有一台受控端负载重&#xff0c;响应慢。当用Ansible连接它时&#xff0c;总是提示超时。 现象 主控端 执行脚本 ansible 192.168.5.37 -m shell -a ip a| grep 192.168.192.168.5.37 | FAILED | rc-1 >> Timeout (12s) waiting for priv…

【Android】Activity task和Instrumentation杂谈

文章目录 activity taskInstrumentation机制参考 Android不仅可以装载众多的系统组件&#xff0c;还可以将它们跨进程组成ActivityTask&#xff0c;这个特性使得每个应用都不是孤立的。 activity task 从数据结构角度看&#xff0c;Task有先后之分&#xff0c;源码实现上采取了…

基于SpringBoot+Vue钢材销售管理系统的设计与实现

系统介绍 为了更好地发挥本系统的技术优势&#xff0c;根据钢材销售管理系统的需求&#xff0c;本文尝试以B/S经典设计模式中的Spring Boot框架&#xff0c;JAVA语言为基础&#xff0c;通过必要的编码处理、钢材销售管理系统整体框架、功能服务多样化和有效性的高级经验和技术…

高级IO简介

一、非阻塞IO 阻塞其实就是进入了休眠状态&#xff0c;交出了 CPU 控制权。 普通文件的读写操作是不会阻塞的&#xff0c;不管读写多少个字节数据&#xff0c; read() 或 write() 一定会在有限的时间内返回&#xff0c;所以普通文件一定是以非阻塞的方式进行 I/O 操作&…

【Visual Studio 2012中文版】下载安装以及使用方法

文章目录 前言一、下载安装包二、安装步骤1.双击VS2012_ULT_chs.iso文件打开2.双击vs_ultimate.exe打开安装程序3.选择要安装的功能4.软件正在安装&#xff0c;请耐心等待10分钟5.安装成功&#xff0c;点击“启动”6.激活码&#xff08;产品密钥&#xff09; 三、VS2012使用&am…

CRMEB Pro版营销功能规则解读

现在&#xff0c;无论是中小型企业拓宽渠道&#xff0c;还是传统企业转型&#xff0c;基本都在考虑布局线上&#xff0c;做微商城是一大趋势&#xff0c;相比传统第三方电商平台&#xff0c;独立部署的商城系统自主性更强&#xff0c;功能开发也更灵活。其中&#xff0c;作为电…

Java基础----字节流和字符流

1.使用字节流拷贝文件夹 import java.io.*;public class Tset01 {public static void main(String[] args) throws IOException {//拷贝一个文件夹&#xff0c;考虑子文件夹//E:\hello -> E:\aaaFile srcnew File("E:\\hello");File destnew File("E:\\dest…

英语写作中available容易忽略的用法

Available 的一般用法没有问题&#xff0c;但它的下面用法容易被我们忽略。 比较下面两句&#xff1a; There is no water. There is no water available. 这两句都翻译为“没有水”&#xff0c;但上一句的意思就是“没有水”&#xff0c;而下一句意味着“需要水但没有水”…