3.7作业

网络聊天室:

程序代码:

ser.c

#include <myhead.h>
//定义消息类型结构体
struct xiaoxi {char type;char name[20];char text[100];
};int main(int argc, const char* argv[])
{// 创建套接字int sfd = socket(AF_INET, SOCK_STREAM, 0);if (sfd  == -1) {perror("socket error");return -1;}// 设置端口快速重用int reuse = 1;if (setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) == -1) {perror("setsockopt error");return -1;}// 绑定// 定义地址信息结构体struct sockaddr_in sin;sin.sin_family = AF_INET;sin.sin_port = htons(atoi(argv[2]));sin.sin_addr.s_addr = inet_addr(argv[1]);if (bind(sfd, (struct sockaddr*)&sin, sizeof(sin)) == -1) {perror("bind error\n");return -1;}// 设置监听if ((listen(sfd, 128)) == -1){perror("listen error\n");return -1;}// 4接受请求// 存储客户端信息结构体struct sockaddr_in cin;cin.sin_family = AF_INET;cin.sin_port = htons(atoi(argv[2]));cin.sin_addr.s_addr = inet_addr(argv[1]);socklen_t socklen = sizeof(cin);struct sockaddr_in arr_cin[1024];// 定义struct pollfd fds[1024];for (int i = 0; i < 1024; i++) {fds[i].fd = -1;fds[i].events = POLLIN;}//将0和sfd放入数组fds[0].fd = 0;fds[1].fd = sfd;struct xiaoxi rec;//消息类型结构体变量char buf[128] = "";//接受消息的容器int newfd = -1; //存储文件描述符while (1) {int res = poll(fds, 1024, -1);if (res < 0){perror("poll error");return -1;}else if (res == 0){printf("time out\n");return -1;}if (fds[0].revents == POLLIN)  //终端标准输入描述符{bzero(buf, sizeof(buf));fgets(buf, sizeof(buf), stdin);buf[strlen(buf) - 1] = 0;for (int j = 4; j < 1024; j++){send(fds[j].fd, buf, sizeof(buf), 0);}}if (fds[1].revents == POLLIN)//sfd{ if ((newfd = accept(sfd, (struct sockaddr*)&cin, &socklen)) == -1) {perror("accept error\n");}arr_cin[newfd] = cin; //将地址信息存入cinprintf("------[%s:%d]连接成功------\n", inet_ntoa(arr_cin[newfd].sin_addr), htons(arr_cin[newfd].sin_port));fds[newfd].fd = newfd; //新生成的文件描述符放入数组fds[newfd].events = POLLIN;}for (int i = 4; i < 1024; i++) {if (fds[i].fd < 0) {continue;}if (fds[i].revents == POLLIN) {bzero(buf, sizeof(buf));bzero(buf, sizeof(buf));int res = recv(fds[i].fd, &rec, sizeof(rec), 0); //接收客户端消息if (res == 0){close(fds[i].fd);printf("------[%s:%d]断开连接------\n", inet_ntoa(arr_cin[fds[i].fd].sin_addr), htons(arr_cin[fds[i].fd].sin_port));fds[i].fd = -1;arr_cin[fds[i].fd].sin_addr.s_addr = 0;arr_cin[fds[i].fd].sin_port = 0;continue;}// 判断消息类型if (rec.type == 'L') // 登录消息{ for (int j = 4; j < 1024; j++)//发送给每个客户端{ if (j == i){continue;}bzero(buf, sizeof(buf));sprintf(buf, "----------%s上线-----------", rec.name);send(fds[j].fd, buf, strlen(buf), 0);}} else if (rec.type == 'C') // 聊天消息{ for (int j = 4; j < 1024; j++) {if (j == i) {continue;}bzero(buf, sizeof(buf));sprintf(buf, "%s:%s", rec.name, rec.text);send(fds[j].fd, buf, strlen(buf), 0);}} else {                        //退出消息//(rec.type == 'Q')for (int j = 4; j < 1024; j++) {if (j == i){continue;}bzero(buf, sizeof(buf));sprintf(buf, "-----------%s下线------------", rec.name);send(fds[j].fd, buf, strlen(buf), 0);}}}}}return 0;
}

cli.c

#include <myhead.h>struct xiaoxi {char type;char name[20];char text[100];
};int main(int argc, const char* argv[])
{// 创建套接字int cfd = socket(AF_INET, SOCK_STREAM, 0);if (cfd  == -1) {perror("socket error\n");return -1;}// 端口快速重用int reus = 1;if ((reus = setsockopt(cfd, SOL_SOCKET, SO_REUSEADDR, &reus, sizeof(reus))) == -1) {perror("setsockopt error\n");return -1;}// 定义地址信息结构体struct sockaddr_in sin;sin.sin_family = AF_INET;sin.sin_port = htons(atoi(argv[2]));sin.sin_addr.s_addr = inet_addr(argv[1]);// 向客户端发送连接请求if (connect(cfd, (struct sockaddr*)&sin, sizeof(sin)) == -1){perror("connect error");return -1;}struct xiaoxi sendi;char buf[100] = "";char nbuf[20] = "";struct pollfd fds[2];fds[0].fd=0;fds[0].events = POLLIN;fds[1].fd=cfd;fds[1].events = POLLIN;printf("请输入用户名:");fgets(nbuf,sizeof(nbuf),stdin);nbuf[strlen(nbuf)-1]=0;sendi.type = 'L';strcpy(sendi.name, nbuf);send(cfd, &sendi, sizeof(sendi), 0);while (1) {int res = poll(fds,2,-1);           //阻塞检测if (fds[0].revents == POLLIN) {bzero(buf, sizeof(buf));fgets(buf,sizeof(buf),stdin);buf[strlen(buf)-1]=0;sendi.type = 'C';    if(strcmp(buf,"quit")==0){sendi.type = 'Q';sendto(cfd, &sendi, sizeof(sendi), 0, (struct sockaddr*)&sin, sizeof(sin));break;}strcpy(sendi.text,buf);sendto(cfd, &sendi, sizeof(sendi), 0, (struct sockaddr*)&sin, sizeof(sin));}if (fds[1].revents == POLLIN){bzero(buf, sizeof(buf));int res = recv(cfd, buf, sizeof(buf), 0);printf("%s\n", buf);if (res == 0) {printf("服务器下线\n");break;}}}close(cfd);return 0;
}

运行结果:

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

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

相关文章

Spring源码:手写AOP

文章目录 一、概念1、AOP是什么&#xff1f;2、相关概念1&#xff09;目标对象Target2&#xff09;通知Advice3&#xff09;连接点Joinpoint4&#xff09;切点Pointcut5&#xff09;切面Aspect6&#xff09;织入Weaving 二、分析三、实现1、实现Advice1&#xff09;前置通知2&a…

企业微信HOOK协议,新设备二次验证处理

提示设备强制二次验证问题已处理 HOOK&#xff1a;https://www.showdoc.com.cn/1663062930779972/7859611259700402密码&#xff1a;999999999

大数据冷热分离方案

数据冷热分离方案 1、背景 ​ 随着业务的发展&#xff0c;在线表中的数据会逐渐增加。常规业务都有冷热数据现象明显的特性&#xff08;需要访问的都是近期产生的热数据&#xff1b;时间久远的冷数据出于备份、备案溯源等诉求会进行在线保留&#xff09;。在业务表数据 量可控…

安卓玩机工具推荐----高通芯片9008端口读写分区 备份分区 恢复分区 制作线刷包 工具操作解析

上期解析了下adb端口备份分区的有关操作 安卓玩机工具推荐----ADB状态读写分区 备份分区 恢复分区 查看分区号 工具操作解析 在以往的博文中对于高通芯片机型的分区读写已经分享了很多。相关类似博文 安卓备份分区----手动查询安卓系统分区信息 导出系统分区的一些基本操作 …

0x04_数组_指针_字符串

数组 数组的定义与使用 数组是具有一定顺序关系的若干相同类型变量的集合体&#xff0c;组成数组的变量称为该数组的元素。 给出下面程序的输出&#xff1a; #include <iostream> using namespace std; int main() {int a[10], b[10];for(int i 0; i < 10; i) {a[…

python 基础知识点(蓝桥杯python科目个人复习计划59)

今日复习内容&#xff1a;做题 例题1&#xff1a;建造房屋 问题描述&#xff1a; 小蓝和小桥是两位年轻的建筑师&#xff0c;他们正在设计一座新的城市。 在这个城市中&#xff0c;有N条街道&#xff0c;每条街道上有M个位置可以建造房屋&#xff08;一个位置只能建造一个房…

2024.3.7 FreeRTOS 作业

思维导图 练习题 1.使用ADC采样光敏电阻数值&#xff0c;如何根据这个数值调节LED灯亮度。 //打开定时器3的通道3&#xff0c;并且设置为PWM功能HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_3);/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1…

【Spring云原生系列】Spring Cloud Stream:消息驱动架构(MDA)解析,实现异步处理与解耦合!

&#x1f389;&#x1f389;欢迎光临&#xff0c;终于等到你啦&#x1f389;&#x1f389; &#x1f3c5;我是苏泽&#xff0c;一位对技术充满热情的探索者和分享者。&#x1f680;&#x1f680; &#x1f31f;持续更新的专栏《Spring 狂野之旅&#xff1a;从入门到入魔》 &a…

相机标定实验

相机标定 文章目录 相机标定1 ROS标定1.1安装标定程序1.2 下载标定板1.3 标定1.4 标定结果 2 Kalibr相机标定2.1 下载官方提供的标定板2.2 自定义标定板2.3 cam数据录制2.4 标定2.5 输出结果 3 MATLAB标定3.1 打开工具3.2 添加标定板图片3.3 设置标定参数3.4 生成标定结果3.5 标…

GIT 卸载干净(图文详解)

一、控制面板卸载 右击卸载 等待卸载过程 二、在环境变量&#xff0c;把相关信息删除干净

微服务架构中实体类模块化设计与MyBatis-Plus注解浅析

引言 在微服务开发过程中&#xff0c;为了保证代码的整洁性和可维护性&#xff0c;我们通常会将VO&#xff08;视图值对象&#xff09;、DTO&#xff08;数据传输对象&#xff09;、DO&#xff08;领域对象&#xff09;等实体类独立组织成一个API模块。这样做的目的是实现代码…

官网:随便搞个?那不如不搞,搞不好就给公司减分了。

官网建设确实需要认真对待&#xff0c;不能随便搞。一个粗制滥造的官网可能会给公司带来负面影响&#xff0c;降低品牌形象和用户体验。以下是一些官网建设的重要原则&#xff1a; 专业性&#xff1a;官网应该展示公司的专业性和专业知识。它应该以专业的设计、内容和功能来展示…

【电路笔记】-NPN晶体管

NPN晶体管 文章目录 NPN晶体管1、概述2、双极NPN晶体管配置3、NPN晶体管中的α和β关系4、示例5、共发射极配置1、概述 NPN 晶体管是三端三层器件,可用作放大器或电子开关。 在前面的文章中,我们看到标准双极晶体管或 BJT 有两种基本形式。 NPN(负-正-负)配置和PNP(正-负…

Nginx启动服务

Nginx启动服务 一、启动前置 下载地址 如已安装Docker&#xff0c;下一步拉取Nginx最新的Docker镜像&#xff1a; docker pull nginx:latest查看拉取下来的镜像&#xff1a; docker images二、启动服务 创建Docker容器&#xff1a; docker run --name {projectname} -p 80…

spring-jpa

一、介绍 1.1ORM 1.2 Java Persistence API 放在javaee版本 优点 支持持久化复杂的Java对象&#xff0c;简化Java应用的对象持久化开发支持使用JPQL语言进行复杂的数据查询使用简单&#xff0c;支持使用注解定义对象关系表之间的映射规范标准化&#xff0c;由Java官 方统一规…

一个系列很多样式的wordpress外贸建站模板

菌菇干货wordpress跨境电商模板 食用菌、羊肚菌、牛肝菌、香菇、干黄花菜、梅干菜、松茸wordpress跨境电商模板。 https://www.jianzhanpress.com/?p3946 餐饮调味wordpress跨境电商模板 豆制品、蛋黄糖、烘焙、咖啡、调料、调味酱、餐饮调味wordpress跨境电商模板。 http…

如何将 ONLYOFFICE 协作空间部署到 Kubernetes / OpenShift 集群中

需要 ONLYOFFICE 协作空间的可扩展实例吗&#xff1f;使用 Helm 轻松将其安装到 Kubernetes 或 OpenShift 集群中。阅读本文了解详情。 ONLYOFFICE 协作空间是什么 ONLYOFFICE 协作空间是一个协同办公平台&#xff0c;能够帮助用户更好地与客户、业务合作伙伴、承包商及第三方…

响应式编程五股票订阅系统实现

响应式编程五 使用StepVerifier测试响应式流StepVerifier要点 使用StepVerifier进行高级测试股票订阅系统数据库表 使用StepVerifier测试响应式流 出于测试目的&#xff0c;Reactor 提供了额外的 reactor-test 模块&#xff0c;该模块提供了 StepVerifier。StepVerifier 提供了…

Easticsearch性能优化之索引优化

Easticsearch性能优化之索引优化 一、合理的索引设计二、合理的分片和副本三、合理的索引设置 对于性能优化&#xff0c;Elasticsearch&#xff08;以下简称ES&#xff09;的索引优化是提高性能的关键因素之一。合理的设计索引&#xff0c;合理的分片和副本以及合理的缓存设置等…

信号处理--卷积残差网络实现单通道脑电的睡眠分期监测

目录 背景 亮点 环境配置 数据 方法 结果 代码获取 参考文献 背景 人类大约花三分之一的时间睡觉&#xff0c;这使得监视睡眠成为幸福感的组成部分。 在本文中&#xff0c;提出了用于端到端睡眠阶段的34层深残留的Convnet架构 亮点 使用深度1D CNN残差架构&#xff0…