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.hqwc.cn/news/106994.html

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

相关文章

首个国家级元宇宙计划发布,和数集团迎来赛道发展新机遇

近日&#xff0c;工业和信息化部、教育部、文化和旅游部、国务院国资委、国家广播电视总局办公厅五部门联合印发《元宇宙产业创新发展三年行动计划&#xff08;2023-2025年&#xff09;》&#xff08;以下简称《计划》&#xff09;&#xff0c;其中在发展目标中提到要培育3-5家…

cf 交互题

今天cf遇到了交互题&#xff0c;这个交互题的算法很很很简单&#xff0c;但是在交互上卡了&#xff0c;导致交上的代码都不算罚时。&#xff08;更伤心了。 所以&#xff0c;现在写一下交互题的做法&#xff0c;印象深刻嘛。 交互题&#xff0c;就是跟机器进行交互。你代码运…

Android MeidiaCodec之OMXPluginBase与QComOMXPlugin实现本质(四十)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药. 更多原创,欢迎关注:Android…

JavaScript中的事件捕获(event capturing)和事件冒泡(event bubbling)

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 事件捕获和事件冒泡⭐ 事件捕获&#xff08;Event Capturing&#xff09;示例&#xff1a; ⭐ 事件冒泡&#xff08;Event Bubbling&#xff09;示例&#xff1a; ⭐ 应用场景⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开…

Python绘图系统16:动态更新tkinter组件

文章目录 前情提要源代码模式输入序列源码 Python绘图系统&#xff1a; &#x1f4c8;从0开始的3D绘图系统&#x1f4c9;一套3D坐标&#xff0c;多个函数&#x1f4ca;散点图、极坐标和子图自定义控件&#xff1a;极坐标&#x1f4c9;绘图风格&#x1f4c9;风格控件图表类型和…

腾讯音乐基于 Apache Doris + 大模型构建全新智能数据服务平台

当前&#xff0c;大语言模型的应用正在全球范围内引发新一轮的技术革命与商业浪潮。腾讯音乐作为中国领先在线音乐娱乐平台&#xff0c;利用庞大用户群与多元场景的优势&#xff0c;持续探索大模型赛道的多元应用。本文将详细介绍腾讯音乐如何基于 Apache Doris 构建查询高效、…

浅谈前后端分离的网络拓扑

前后端分离大体分为两种拓扑结构&#xff0c;前端和后端通过开放对外端口的拓扑结构和只有前端开放端口的拓扑结构 前端和后端通过开放对外端口的拓扑结构 比如说前端通过 80 端口对外提供服务&#xff0c;后端通过 8080 端口对外提供服务&#xff0c;前端和后端搭建在同一台服…

Mybatis-Plus 使用教程

01-Mybatis-Plus介绍 1.1 什么是mybatis-plus 官网: 简介 | MyBatis-Plus MyBatis-Plus&#xff08;简称 MP&#xff09;是一个 MyBatis 的增强工具&#xff0c;在 MyBatis 的基础上只做增强不做改变&#xff0c;为简化开发、提高效率而生。 1.2 官方愿景 1.3 特性 无侵入&…

vue2配置环境变量并且nginx运行成功

需求&#xff1a;我在vue项目配置了生产环境和开发环境&#xff0c;之后通过proxy代理的方式把地址转发到真实的服务器地址上用于请求接口&#xff0c;之后把项目打包后上传到nginx上&#xff0c;之后接口报错404&#xff0c;但是本地运行是可以访问的&#xff0c;找了很久终于…

腾讯云centos7.6安装部署备忘

1.Mysql 1.1 安装mysql wget http://dev.mysql.com/get/mysql-community-release-el7-5.noarch.rpm rpm -ivh mysql-community-release-el7-5.noarch.rpm yum install mysql-community-server 1.1.1 安装后重启 service mysqld restart 1.1.2 初次安装mysql&#xff0c;root账…

linux服务器内服务访问域名Name or service not know

目录 linux服务器内服务访问域名Name or service not know 1.前言2.排查是不是这个域名无法访问2.1服务内ping 这个域名2.2在浏览器打开这个域名2.3服务内ping 这个域名所对应的ip2.4在服务器内配置host 总结参考 文章所属专区 项目问题解决 1.前言 linux服务器内服务访问域名…

算法通关村第十九关:青铜-动态规划是怎么回事

青铜挑战-动态规划是怎么回事 动态规划&#xff08;简称DP&#xff0c;Dynamic Programming&#xff09;&#xff1a;最热门、最重要的算法之一。面试中大量出现&#xff0c;整体偏难。 1. 热身&#xff1a;重复计算和记忆化搜索&#xff08;如何说一万次"我爱你"&…