网络编程聊天室

 客户端

#include <myhead.h>
//创建结构体存储用户信息
struct User
{char tape;char username[32];char msg[1024];
};int main(int argc, const char *argv[])
{//创建套接字与服务器进行通信int sfd=socket(AF_INET,SOCK_STREAM,0);if(sfd==-1){perror("socket error");return -1;}//绑定//填充服务器结构体数据struct sockaddr_in sin;sin.sin_family=AF_INET;sin.sin_port=htons(8888);sin.sin_addr.s_addr=inet_addr("192.168.125.86");char username[32]="";struct User user;strcpy(&user.tape,"L");//创建容器存储文件标识符fd_set readfds,tempfds;//清空容器FD_ZERO(&readfds);FD_SET(0,&readfds);FD_SET(sfd,&readfds);int maxfd=sfd;while(1){tempfds=readfds;int res=select(maxfd+1,&tempfds,NULL,NULL,NULL);if(res==-1){perror("select error");return -1;}for(int i=0;i<=maxfd;i++){if(!FD_ISSET(i,&tempfds)){continue;}	//向服务器读取消息else if(sfd==i){if(user.tape=='L'){//向服务器发送数据(用户结构体)printf("请输入登录用户>>>");scanf("%s",username);strcpy(user.username,username);if(connect(sfd,(struct sockaddr*)&sin,sizeof(sin))==-1){perror("connect error");return -1;};//发送只有用户名和结构类型send(sfd,&user,sizeof(user),0);user.tape='C';}else if(user.tape=='C'){char Msg[2046]="";int len=recv(sfd,Msg,sizeof(Msg),0);if(len>=0){printf("%s",Msg);}else if(len==-1){perror("recv error");}}}//向服务器发送数据else if(i==0&&user.tape=='C'){char msg[1024]="";//向服务器发送数据(用户结构体)scanf("%s",msg);	strcpy(user.msg,msg);if(strcmp(user.msg,"quit")==0){user.tape='Q';send(sfd,&user,sizeof(user),0);goto A;}send(sfd,&user,sizeof(user),0);}}}
A:close(sfd);return 0;
}

服务器端

#include <myhead.h>
struct userdata
{char tape;char username[32];char msg[1024];
};int main(int argc, const char *argv[])
{//创建套接字文件与客户端连接int sfd=socket(AF_INET,SOCK_STREAM,0);if(sfd==-1){perror("socket error");return -1;}signal(SIGPIPE, SIG_IGN);//绑定服务器信息//填充服务器信息struct sockaddr_in sin;sin.sin_family=AF_INET;sin.sin_port=htons(8888);sin.sin_addr.s_addr=inet_addr("192.168.125.86");socklen_t ssocklen=sizeof(sin); //重新启用端口int resue=1;setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,&resue,sizeof(resue));//绑定if(bind(sfd,(struct sockaddr*)&sin,sizeof(sin))==-1){perror("bind error");return -1;}char mbuf[2048]="";//监听if(listen(sfd,168)==-1){perror("listen error");return -1;}//定义容器接收对端地址信息结构体struct sockaddr_in cin;	socklen_t socklen=sizeof(cin);int newfd=-1;char sbuf[128]="";//创建容器存储文件描述符fd_set readfds,tempfds;//清空容器FD_ZERO(&readfds);FD_SET(0,&readfds);FD_SET(sfd,&readfds);int maxfd=sfd;struct sockaddr_in cin_arr[1024];while(1){//保留容器tempfds=readfds;int res=select(maxfd+1,&tempfds,NULL,NULL,NULL);//	printf("res=%d\n",res);if(res==-1){perror("select error");return -1;}else if(res==0){printf("TIME OUT\n");return -1;}for(int i=0;i<=maxfd;i++){struct userdata Users;char Tape=Users.tape;	if(!FD_ISSET(i,&tempfds)){continue;}else if(i==sfd)  //表示sfd触发了事件{newfd=accept(sfd,(struct sockaddr*)&cin,&socklen);if(newfd==-1){perror("accept error");return -1;}//服务器显示用户上线,并且广播给其他用户recv(newfd,&Users,sizeof(struct userdata),MSG_DONTWAIT);memset(Users.msg,0,sizeof(Users.msg));Tape=Users.tape;	//更新maxfdif(newfd>maxfd){	maxfd=newfd;}if(Tape=='L'){//将用户信息存储char str[128]="";sprintf(str,"用户[%s]已上线\n",Users.username);printf("%s",str);for(int j=4;j<=maxfd;j++){if(j==newfd){continue;}send(j,str,sizeof(str),0);}}//将客户端放入数组FD_SET(newfd,&readfds);tempfds=readfds;cin_arr[newfd]=cin;break;}else if(i==0){fgets(sbuf,sizeof(sbuf),stdin);sbuf[strlen(sbuf)-1]=0;printf("触发键盘输入\n");char ssbuf[1024]="";sprintf(ssbuf,"服务器发来消息:%s\n",sbuf);for(int k=4;k<=maxfd;k++){send(k,ssbuf,strlen(ssbuf),0);}}else{//与客户端进行数据收发//定义一个结构体存储客户端发来的正文recv(i,&Users,sizeof(struct userdata),MSG_DONTWAIT);Tape=Users.tape;printf("%c\n",Tape);//接收客户端发来的数据if(Tape=='C'){//创建数组char mbuf[2046]="";sprintf(mbuf,"用户[%s]发送消息:%s\n",Users.username,Users.msg);printf("%s\n",mbuf);for(int j=4;j<=maxfd;j++){if(j==i){continue;}send(j,mbuf,sizeof(mbuf),0);}}else if(Tape=='Q'){//创建数组char msg[1024]="";sprintf(msg,"用户[%s]已下线\n",Users.username);printf("%s\n",msg);for(int j=4;j<=maxfd;j++){if(j==i){continue;}send(j,msg,sizeof(msg),0);}//关闭套接字close(i);//将当前文件描述符从容器中移除FD_CLR(i,&readfds);//更新maxfdfor(int j=maxfd;j>=0;j--){if(FD_ISSET(j,&readfds)){maxfd=j;break;}}continue;} }}}return 0;
} 

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

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

相关文章

鸿蒙实战开发Camera组件:【相机】

相机组件支持相机业务的开发&#xff0c;开发者可以通过已开放的接口实现相机硬件的访问、操作和新功能开发&#xff0c;最常见的操作如&#xff1a;预览、拍照和录像等。 基本概念 拍照 此功能用于拍摄采集照片。 预览 此功能用于在开启相机后&#xff0c;在缓冲区内重复采集…

django默认后台管理显示内容深化设置

1、设置models字段展示为只读模式 如某个字段在展示时不允许修改&#xff0c;可在admin.py的注册类下重写函数get_readonly_fields&#xff0c;例&#xff1a; def get_readonly_fields(self, request, objNone): return (dwdm,dwmc,"zjs","yyj"…

ARC-Challenge数据集分享

来源: AINLPer公众号&#xff08;每日干货分享&#xff01;&#xff01;&#xff09; 编辑: ShuYini 校稿: ShuYini 时间: 2024-2-28 该数据集由Allen Institute for Artificial Intelligence&#xff08;AI2&#xff09;发布&#xff0c;旨在推动高级问答的研究。该数据集包含…

#微信小程序(按键控制)

1.IDE&#xff1a;微信开发者工具 2.实验&#xff1a;微信小程序设计两个按钮&#xff0c;对onenet平台数据流&#xff08;旧版&#xff09;来进行http post上传&#xff0c;下位机再http get得到控制信息 3.记录 &#xff08;1&#xff09;bind-tap&#xff08;绑定函数&…

3D数字孪生运行不起来?该检查你的电脑配置了

运行3D数字孪生项目通常需要一定的计算资源和图形处理能力。以下是一些常见的电脑配置要求&#xff0c;可以作为参考&#xff1a;1处理器&#xff08;CPU&#xff09;&#xff1a;推荐使用多核心处理器&#xff0c;如Intel Core i7或更高级别的处理器。较高的时钟频率和较大的缓…

Linux shell 网络掩码地址转CIDR

例子&#xff1a; ./1.sh 255.255.255.0 ./1.sh 255.255.255.128 ./1.sh 255.255.0.0 源实现&#xff1a; #!/bin/bashnetmask_to_cidr() {local IFSlocal -a octetslocal i0local cidr0IFS. read -r -a octets <<< "$1"for octet in "${octets[]}…

Sora关于视频分镜的提示词技巧

视频分镜是视频制作中至关重要的一环&#xff0c;它决定了视频内容的结构、节奏和视觉效果。在Sora文生视频模型中&#xff0c;通过巧妙地运用提示词&#xff0c;你可以更加高效地进行视频分镜设计&#xff0c;提升视频的质量和观众体验。以下是10个关于视频分镜的提示词技巧&a…

kafka报文模拟工具的使用

日常项目中经常会碰到消费kafka某个topic的数据&#xff0c;如果知道报文格式&#xff0c;即可使用工具去模拟发送报文&#xff0c;以此测试代码中是否能正常消费到这个数据。 工具资源已上传&#xff0c;可直接访问连接下载&#xff1a;https://download.csdn.net/download/w…

CSS补充(下),弹性布局(上)

高级选择器 1.兄弟选择器 2.同时满足 div.bg{background-color: red;}p.bg{background-color: green;}spam.bg{background-color: blue;}注&#xff1a;选择器中间没有空格&#xff0c;有明确标识的选择器写在后面 3.各种伪类的应用 3.1作为第几个子元素 选择器:nth-child…

React-父传子

1.概念 说明&#xff1a;父组件传递数据子组件标签身上绑定属性&#xff1b;子组件接受数据props的参数。props是一个对象&#xff0c;包含父组件传递的所有数据。例如数字、字符串、布尔值、数组、对象、函数、JSX。不允许直接修改父组件传递的数据。 2.例子 // 父传子 // …

uniapp踩坑之项目:uni.previewImage简易版预览单图片

主要使用uni.previewImage //html <view class"box-card" v-for"(item,index) in DataList" :key"index"><view>图片&#xff1a;</view><image :src"item.Path" tap.stop"clickImg(item.Path)">&l…

有点NB的免费wordpress主题模板

一个不错的黄色模板&#xff0c;用WP免费主题模板搭建家政服务公司网站。 https://www.wpniu.com/themes/15.html

【性能】JDK和Jmeter的安装与配置

一、JDK环境配置 1. 下载JDK 官网下载地址&#xff1a;http://www.oracle.com/technetwork/java/javase/downloads/java-archive-downloads-javase7-521261.html 选择对应系统的安装包&#xff0c;下载后安装&#xff0c;安装中记录JDK安装的地址&#xff0c;之后一直点击下一…

继深圳后,重庆与鸿蒙展开原生应用开发合作

截至2023年底&#xff0c;开源鸿蒙开源社区已有250多家生态伙伴加入&#xff0c;开源鸿蒙项目捐赠人达35家&#xff0c;通过开源鸿蒙兼容性测评的伙伴达173个&#xff0c;累计落地230余款商用设备&#xff0c;涵盖金融、教育、智能家居、交通、数字政府、工业、医疗等各领域。 …

【Python】科研代码学习:三 PreTrainedModel, PretrainedConfig, PreTrainedTokenizer

【Python】科研代码学习&#xff1a;三 PreTrainedModel, PretrainedConfig, PreTrainedTokenizer 前言Models : PreTrainedModelPreTrainedModel 中重要的方法 tensorflow & pytorch 简单对比Configuration : PretrainedConfigPretrainedConfig 中重要的方法 Tokenizer : …

Java基础面试题(day 01)

&#x1f4d1;前言 本文主要是【Java】——Java基础面试题的文章&#xff0c;如果有什么需要改进的地方还请大佬指出⛺️ &#x1f3ac;作者简介&#xff1a;大家好&#xff0c;我是听风与他&#x1f947; ☁️博客首页&#xff1a;CSDN主页听风与他 &#x1f304;每日一句&am…

C++ 篇 数组

数组是含有多个数据项的数据结构&#xff0c;并且这些数据项都具有相同的数据类型。这些数据项称为数组的元素&#xff0c;我们可以根据元素在数组中的位置来选取元素。 最简单的数组就是一维数组。数组元素在内存中是依次排列的&#xff0c;如下图所示&#xff1a; 声明一个…

C++之创建与使用dll

目录 1、创建dll test.h test.cpp Source.def 2、使用dll testdll.cpp DLL&#xff0c;全称“Dynamic Link Library”&#xff0c;中文名为“动态链接库”&#xff0c;是一种在Windows操作系统中常见的库文件格式。它包含了可以由多个程序同时使用的代码和数据。与静态链接…

09 函数和存储过程

文章目录 函数和存储过程函数创建存储过程创建存储过程和存储函数操作函数和存储过程区别 函数和存储过程 存储过程和函数是事先经过编译并存储在数据库中的一段sql语句集合&#xff0c;调用存储过程和函数可以简化应用开发工作&#xff0c;提高数据处理的效率。 函数创建 d…

人工智能|机器学习——k-近邻算法(KNN分类算法)

1.简介 k-最近邻算法&#xff0c;也称为 kNN 或 k-NN&#xff0c;是一种非参数、有监督的学习分类器&#xff0c;它使用邻近度对单个数据点的分组进行分类或预测。虽然它可以用于回归问题&#xff0c;但它通常用作分类算法&#xff0c;假设可以在彼此附近找到相似点。 对于分类…