9月1日作业

思维导图

服务器代码

#include<myhead.h>#define PORT 4567
#define IP "192.168.6.225"struct msg //接收到的客户端信息结构体
{char type;char name[20];char txt[128];
};//定义节点类型
typedef struct Node
{union{struct sockaddr_in cin;      //数据域int len;             //头结点数据域};struct Node *next;      //指针域
}Node, *LinkListPtr;struct task
{LinkListPtr L;int sfd;
};//创建链表
LinkListPtr list_create();//判空操作
int list_empty(LinkListPtr L);//申请结点封装数据函数
LinkListPtr node_buy(struct sockaddr_in cin);//头插
int list_insert_head(LinkListPtr L, struct sockaddr_in cin);//遍历链表,发送数据
int list_show(LinkListPtr L, int sfd, char *buf);void *send_cli_msg(void *arg);int main(int argc, const char *argv[])
{//创建报式套接字int sfd = socket(AF_INET, SOCK_DGRAM, 0);if(sfd < 0){ERR_MSG("socket");return -1;}printf("socket success\n");//允许端口能被快速复用int reuse = 1;if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0){ERR_MSG("setsockopt");return -1;}printf("允许端口被快速复用成功\n");//填充服务器地址信息结构体struct sockaddr_in sin;sin.sin_family = AF_INET;sin.sin_port = htons(PORT);sin.sin_addr.s_addr = inet_addr(IP);//bind函数绑定服务器地址信息if(bind(sfd, (struct sockaddr*)&sin, sizeof(sin)) < 0){ERR_MSG("bind");return -1;}printf("bind success\n");struct sockaddr_in cin;  		 //定义客户端地址信息结构体socklen_t addrlen = sizeof(cin); struct msg climsg;               //定义存放客户端信息结构体pthread_t tid;LinkListPtr L = list_create();struct task taskin;taskin.L = L;taskin.sfd = sfd;while(1){//接受信息if(recvfrom(sfd, (struct msg*)&climsg, sizeof(climsg), 0, (struct sockaddr*)&cin, &addrlen) < 0){ERR_MSG("recv");return -1;}if(climsg.type == 'L'){printf("----%s----已上线\n",climsg.name); //打印客户端上线char buf2[128];sprintf(buf2, "----%s----已上线", climsg.name);list_insert_head(L, cin);//加入链表list_show(L, sfd, buf2);}else if(climsg.type == 'C'){printf("%s: %s\n",climsg.name, climsg.txt);char buf2[128];strcpy(buf2, climsg.name);strcat(buf2, climsg.txt);list_show(L, sfd, buf2);}else if(climsg.type == 'Q'){printf("----%s----已下线\n",climsg.name); //打印客户端上线char buf2[128];sprintf(buf2, "----%s----已下线", climsg.name);list_show(L, sfd, buf2);}if(pthread_create(&tid, NULL, send_cli_msg, (void*)&taskin) != 0){fprintf(stderr, "pthread_create failed__%d__\n", __LINE__);return -1;}//线程分离pthread_detach(tid);}if(close(sfd) < 0) //关闭文件描述符{ERR_MSG("close");return -1;}return 0;
}void *send_cli_msg(void *arg)
{LinkListPtr L = ((struct task*)arg)->L;int sfd = ((struct task*)arg)->sfd;//群发消息char buf1[128] = "";bzero(buf1, sizeof(buf1));scanf("%s", buf1);list_show(L, sfd, buf1);
}//创建链表
LinkListPtr list_create()
{//在堆区申请一个头结点类型LinkListPtr L = (LinkListPtr)malloc(sizeof(Node));if(NULL == L){printf("创建失败\n");return NULL;}//创建成功,对节点进行初始化L->len = 0;       //初始链表长度为0L->next = NULL;     //链表上没有任何结点printf("创建链表成功\n");return L;
}//判空操作
int list_empty(LinkListPtr L)
{//判断逻辑if(NULL == L){printf("所给链表不合法\n");return -1;}//判断指针域的内容return L->next == NULL && L->len==0;
}//申请结点封装数据函数
LinkListPtr node_buy(struct sockaddr_in cin)
{//在堆区申请结点LinkListPtr p = (LinkListPtr)malloc(sizeof(Node));if(NULL == p){printf("结点申请失败\n");return NULL;}//结点申请成功,将数据封装进去p->cin = cin;p->next = NULL;return p;
}//头插
int list_insert_head(LinkListPtr L, struct sockaddr_in cin)
{//判断逻辑if(NULL == L){printf("所给链表不合法\n");return 0;}//调用申请结点封装数据LinkListPtr p = node_buy(cin);if(NULL==p){return 0;}//结点已经准备好,头插逻辑p->next = L->next;L->next = p;//表的变化L->len++;printf("插入成功\n");return 1;
}//遍历链表,发送数据
int list_show(LinkListPtr L, int sfd, char *buf)
{//判断逻辑if(NULL==L || list_empty(L)){printf("遍历失败\n");return -1;}//遍历逻辑printf("群发开始");//1、定义遍历指针从第一个结点开始LinkListPtr q = L->next;while(q != NULL)     //2、只要当前结点存在{//发送if(sendto(sfd, buf, 128, 0, (struct sockaddr*)&(q->cin), sizeof(q->cin)) < 0){ERR_MSG("send");return -1;}q = q->next;        //4、指针后移}printf("\n");
}

客户端代码

#define PORT 4567
#define IP "192.168.6.225"struct msg //客户端信息结构体
{char type;char name[20];char txt[128];
};struct serinfo //线程函数传参结构体
{int cfd;struct sockaddr_in sin;char name[20];
};void *send_ser_msg(void *arg);int main(int argc, const char *argv[])
{//创建报式套接字int cfd = socket(AF_INET, SOCK_DGRAM, 0);if(cfd < 0){ERR_MSG("socket");return -1;}printf("socket success\n");//允许端口能被快速复用int reuse = 1;if(setsockopt(cfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0){ERR_MSG("setsockopt");return -1;}printf("允许端口被快速复用成功\n");//填充服务器地址信息结构体struct sockaddr_in sin;sin.sin_family = AF_INET;sin.sin_port = htons(PORT);sin.sin_addr.s_addr = inet_addr(IP);char buf[128] = ""; 			 //定义字符串容器struct sockaddr_in cin;  		 //定义客户端地址信息结构体socklen_t addrlen = sizeof(cin); pthread_t tid;struct serinfo info;info.cfd = cfd;info.sin = sin;struct msg climsg;//登录操作char name[20];printf("请输入用户名\n");scanf("%s", name);climsg.type = 'L';strcpy(climsg.name, name);strcpy(climsg.txt, "");strcpy(info.name, name);//发送if(sendto(cfd, (struct msg*)&climsg, sizeof(climsg), 0, (struct sockaddr*)&sin, sizeof(sin)) < 0){ERR_MSG("sendto");return -1;}while(1){if(pthread_create(&tid, NULL, send_ser_msg, (void*)&info) != 0){fprintf(stderr, "pthread_create failed__%d__\n", __LINE__);return -1;}bzero(buf, sizeof(buf));//接受信息if(recvfrom(cfd, buf, sizeof(buf), 0, (struct sockaddr*)&sin, &addrlen) < 0){ERR_MSG("recv");return -1;}printf("server[%s:%d] rcvdata = %s\n", inet_ntoa(sin.sin_addr),\ntohs(sin.sin_port), buf);//线程分离pthread_detach(tid);}if(close(cfd) < 0) //关闭文件描述符{ERR_MSG("close");return -1;}return 0;
}void *send_ser_msg(void *arg)
{int cfd = ((struct serinfo*)arg)->cfd;struct sockaddr_in sin = ((struct serinfo*)arg)->sin;char name[20];strcpy(name, ((struct serinfo*)arg)->name);char buf1[128] = "";struct msg climsg;while(1){scanf("%s", buf1);if(strcmp((buf1), "quit") == 0){climsg.type = 'Q';strcpy(climsg.name, name);strcpy(climsg.txt, "quit");if(sendto(cfd, (struct msg*)&climsg, sizeof(climsg), 0, (struct sockaddr*)&sin, sizeof(sin)) < 0){ERR_MSG("sendto");return NULL;}exit(0);}else{climsg.type = 'C';strcpy(climsg.name, name);strcpy(climsg.txt, buf1);//发送if(sendto(cfd, (struct msg*)&climsg, sizeof(climsg), 0, (struct sockaddr*)&sin, sizeof(sin)) < 0){ERR_MSG("sendto");return NULL;}}}
}

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

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

相关文章

SpringMVC增删改查(CRUD)的实现

目录 前言 一、前期准备 1.pom.xml---依赖与插件的导入 2.jdbc.properties---数据库连接 3.log4j2.xml---日志文件 4.spring-mybatis---mybatis与spring整合文件 5.spring-context---spring上下文配置 6.spring-mvc 7.generatorConfig.xml---代码生成器 8.web.xml 二…

核心实验16_端口镜像_ENSP

项目场景&#xff1a; 核心实验16_端口镜像_ENSP 实搭拓扑图&#xff1a; 具体操作&#xff1a; 交换机: [garliccc]observe-port 1 interface GigabitEthernet 0/0/3 /设置0/0/3为观察口 [garliccc]int g0/0/2 [garliccc-GigabitEthernet0/0/2]port-mirroring to observe-po…

win 10 安装新程序总是弹出提示:目前无法访问smartscreen

win 10 安装新程序总是弹出提示&#xff1a;目前无法访问smartscreen 因为后来无法再现警告&#xff0c;无法截图 搜索安全&#xff0c;找到 Windows 安全中心 找到“应用和浏览器控制”&#xff0c;关闭其中 2 项 SmartScreen 奇怪的是&#xff0c;之后我又改回去了&#x…

npm install失败的分析与解决方案,以及修复完成的代码地址

问题描述&#xff1a; 在引入vue-element-admin后npm i 初始化失败&#xff0c;或者对下载的vue项目npm i 任何插件都会失败&#xff0c;且安装依赖时报错 npm ERR! Error while executing npm ERR! Error while executing: npm ERR! H:\Program Files\git\Git\cmd\git.EXE ls…

接口测试(详细总结)

序章 ​ 说起接口测试&#xff0c;网上有很多例子&#xff0c;看了不不知道他们说的什么&#xff0c;觉得接口测试&#xff0c;好高大上。认为学会了接口测试就能屌丝逆袭&#xff0c;走上人生巅峰&#xff0c;迎娶白富美。因此学了点开发知识后&#xff0c;发现接口测试其实都…

第P4周:猴痘病识别

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f366; 参考文章&#xff1a;Pytorch实战 | 第P4周&#xff1a;猴痘病识别&#x1f356; 原作者&#xff1a;K同学啊|接辅导、项目定制 一、前期准备 1.设置GPU 设置GPU device torch.device…

系统架构设计师-嵌入式系统

目录 一、嵌入式系统概述 1、基本概念 2、嵌入式系统软件组成架构 二、嵌入式软件开发 三、嵌入式硬件 1、嵌入式微处理器 2、人工智能芯片 3、嵌入式微处理器体系结构 4、总线 四、嵌入式操作系统 1、嵌入式实时操作系统 2、操作系统内核架构 3、鸿蒙操作系统 五、嵌入式…

postman token 请求头添加

思路&#xff1a; 1、登录成功后将 得到的token设置为集合变量 2、在需要携带Authorization的请求头上使用该集合变量 关键代码 const responseData pm.response.json(); if(responseData.code 1) {// 获取tokenconst {data:{token}} responseData// 设置为集合变量pm.colle…

编译OpenWrt内核驱动

编译OpenWrt内核驱动可以参考OpenWrt内部其它驱动的编写例程&#xff0c;来修改成自己需要的驱动 一、OpenWrt源代码获取与编译 1.1、搭建环境 下载OpenWrt的官方源码&#xff1a; git clone https://github.com/openwrt/openwrt.git1.2、安装编译依赖项 sudo apt update -…

vue中如何给特殊字段设置插槽

大纲: <template><div><div><span>卡号</span><el-input type"text" v-model"cardNo" clearable placeholder"请输入卡号" /><el-button type"primary" plain icon"el-icon-search"…

我们如何在工作与生活中找到平衡点?

找到工作与生活中的平衡点是每个人都必须面对的问题。以下是一些建议&#xff0c;可以帮助你在工作和生活之间找到平衡&#xff1a; 制定时间表&#xff1a;确保你有足够的时间来处理工作和生活中的各种任务。为工作、学习和个人生活设定优先级&#xff0c;并确保时间分配合理…

ElasticSearch第三讲:ES详解 - Elastic Stack生态和场景方案

ElasticSearch第三讲&#xff1a;ES详解 - Elastic Stack生态和场景方案 本文是ElasticSearch第三讲&#xff0c;在了解ElaticSearch之后&#xff0c;我们还要了解Elastic背后的生态 即我们常说的ELK&#xff1b;与此同时&#xff0c;还会给你展示ElasticSearch的案例场景&…

浅谈限流式保护器在高校防火工作的应用

安科瑞 华楠 【摘要】摘要&#xff1a;为了预防火灾和减少火灾带来的危害&#xff0c;保护校园和师生生命财产安全&#xff0c; 建和谐安宁的校园环境&#xff0c;保障学校安全稳定发展&#xff0c;我们必须要时刻拧紧消防安全这弦&#xff0c;时刻注意这根高压线。随着近年来…

el-select下拉框定位问题

1.当el-select所在页面滚动时或者el-select上面区域高度发生变化时&#xff0c;定位存在偏差 2.解决办法&#xff1a; 1. el-select自带属性popper-append-to-body&#xff1a;true&#xff0c;可能会无效 2.设置ref,监听高度变化或者滚动时&#xff0c;手动执行刷新方法&…

应用在汽车新风系统中消毒杀菌的UVC灯珠

在病毒、细菌的传播可以说是一个让人敏感而恐惧的事情。而对于车内较小的空间&#xff0c;乘坐人员流动性大&#xff0c;更容易残留细菌病毒。车内缺少通风&#xff0c;残留的污垢垃圾也会滋生细菌&#xff0c;加快细菌的繁殖。所以对于车内消毒就自然不容忽视。 那么问题又来…

算法:贪心---跳一跳

1、题目&#xff1a; 给你一个非负整数数组 nums &#xff0c;你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后一个下标&#xff0c;如果可以&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 2…

【SpringMvc 丨跨域】

Spring MVC 支持跨域处理&#xff08;CORS&#xff09;。 CORS 简介处理CORS 过滤器CrossOrigin注解java配置xml配置 主页传送门&#xff1a;&#x1f4c0; 传送 简介 跨域是指在浏览器的同源策略下&#xff0c;不能执行其他网站的脚本。它是由浏览器的安全限制造成的&#xf…

2023-9-12 完全背包问题

题目链接&#xff1a;完全背包问题 初版(时间复杂度拉满) #include <iostream> #include <algorithm>using namespace std;const int N 1010;int n, m; int v[N], w[N]; int f[N][N];int main() {cin >> n >> m;for(int i 1; i < n; i ) cin >…

欧洲汽车制造商押注电力合成燃料 | 2023中国可持续燃料峰会

欧洲几家汽车制造商表示&#xff0c;所谓的电力合成燃料(e-fuels&#xff0c;利用可再生电力合成的化石燃料&#xff0c;又称电子燃料)将在欧洲汽车行业的未来发挥关键作用&#xff0c;它们相信&#xff0c;布鲁塞尔方面在替代燃料问题上的让步&#xff0c;将使它们能够在未来1…

VoxWeekly|The Sandbox 生态周报|20230904

欢迎来到由 The Sandbox 发布的《VoxWeekly》。我们会在每周发布&#xff0c;对上一周 The Sandbox 生态系统所发生的事情进行总结。 如果你喜欢我们内容&#xff0c;欢迎与朋友和家人分享。请订阅我们的 Medium 、关注我们的 Twitter&#xff0c;并加入 Discord 社区&#xf…