网络编程Day6

网络聊天室

服务器

#include <myhead.h>
#define SER_IP "192.168.125.64"
#define SER_PORT 6666
typedef struct Msg
{char user[32];   //用户名int type;        //1.登录、2.发消息、0.退出char text[1024]; //消息
} msg_t;
typedef struct List
{struct sockaddr_in cin; //客户端网络信息结构体struct List *next;      //链表指针
} * list;struct sockaddr_in cin;
//创建头节点
list list_create()
{list p = (list)malloc(sizeof(struct List));if (p == NULL){perror("create list error");}p->next = NULL;p = NULL;
}//向所有客户端发送消息
void *task(void *arg)
{int *sockfd = (int *)arg;msg_t msg;strcpy(msg.user, "*system*");while (1){scanf("%s", msg.text);getchar();if (strncmp(msg.text, "quit", 4) == 0){exit(0);}sendto(*sockfd, msg.text, sizeof(msg), 0, (struct sockaddr *)&cin, sizeof(cin));}
}
//登录
void login(int sockfd, msg_t msg, list p, struct sockaddr_in cin)
{list newusr = NULL;new = (list)malloc(sizeof(struct List));sprintf(msg.text, "login");while (p->next != NULL){//发送给其他客户端登录消息p = p->next;sendto(sockfd, &msg, sizeof(msg), 0, (struct sockaddr *)&(p->cin), sizeof(p->cin));printf("[%s:%d]:%s login\n", inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), msg.user);}//新节点的数据域填充新客户地址结构体newusr->cin = cin;p->next = new;new->next = NULL;
}
//接收客户端消息事件处理
void chatmsg(int sockfd, msg_t msg, list p, struct sockaddr_in cin)
{//将客户端发来的消息发送给其他客户端while (p->next != NULL){p = p->next;sendto(sockfd, &msg, sizeof(msg), 0, (struct sockaddr *)&(p->cin), sizeof(p->cin));}
}//客户端退出
void quit(int sockfd, msg_t msg, list p, struct sockaddr_in cin)
{list del = NULL;sprintf(msg.text, "%s out", msg.user);while (p->next != NULL){//遍历链表找要退出的客户端地址结构体的前一个if (memcmp(&(p->next->cin), &cin, sizeof(cin)) == 0){del = p->next;p->next = del->next;free(del);del = NULL;}else{p = p->next;sendto(sockfd, &msg, sizeof(msg), 0, (struct sockaddr *)&(p->cin), sizeof(p->cin));}}
}
int main(int argc, char const *argv[])
{msg_t msg;//创建套接字int sockfd = socket(AF_INET, SOCK_DGRAM, 0);if (sockfd == -1){perror("socket error");return -1;}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(sockfd, (struct sockaddr *)&sin, sizeof(sin)) == -1){perror("bind error");return -1;}//创建客户端地址结构体struct sockaddr_in cin;//获取客户端地址结构体大小socklen_t socklen = sizeof(cin);//创建链表节点list p = list_create();//创建线程pthread_t tid;if (pthread_create(&tid, NULL, task, &sockfd) == -1){printf("pthread_create error\n");return -1;}//分离线程pthread_detach(tid);//接收客户端消息while (1){//接收客户端发来的消息,返回消息字符个数int res = recvfrom(sockfd, &msg, sizeof(msg), 0, (struct sockaddr *)&cin, &socklen);if (res < 0){perror("recvfrom error");return -1;}//判断客户端状态 登录(1) 消息(2) 退出(0)if (msg.type == 1){login(sockfd, msg, p, cin);}else if (msg.type == 2){chatmsg(sockfd, msg, p, cin);}else if (msg.type == 0){printf("[%s:%d] %s out\n", inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), msg.user);quit(sockfd, msg, p, cin);}}//关闭套接字close(sockfd);return 0;
}

客户端

#include <myhead.h>
#define SER_IP "192.168.125.64"
#define SER_PORT 6666typedef struct Msg
{char user[32];   //用户名int type;        //1登录、2发消息、0退出char text[1024]; //消息
} msg_t;int main(int argc, char const *argv[])
{int sockfd = socket(AF_INET, SOCK_DGRAM, 0);if (sockfd == -1){perror("sock error");return -1;}msg_t msg;struct sockaddr_in cin;cin.sin_family = AF_INET;cin.sin_addr.s_addr = inet_addr(SER_IP);cin.sin_port = htons(SER_PORT);socklen_t socklen = sizeof(cin);char buf[128] = "";msg.type = 1;printf("please imput your name:");scanf("%s", msg.user);getchar();sendto(sockfd, &msg, sizeof(msg), 0, (struct sockaddr *)&cin, socklen);pid_t pid = fork();if (pid < 0){perror("fork error");return -1;}//子进程循环else if (pid == 0){while (1){printf("---------------------\n");scanf("%s", msg.text);getchar();if (strncmp(msg.text, "quit", 4) == 0){msg.type = 0;sendto(sockfd, &msg, sizeof(msg), 0, (struct sockaddr *)&cin, socklen);kill(pid, SIGINT);exit(0);wait(NULL);}else{msg.type = 2;}sendto(sockfd, &msg, sizeof(msg), 0, (struct sockaddr *)&cin, socklen);}}//父进程循环接收消息else {int res;while (1){res = recv(sockfd, &msg, sizeof(msg), 0);if (res == -1){perror("recv error");return -1;}printf("[%s]:%s\n", msg.user, msg.text);}wait(NULL);}close(sockfd);return 0;
}

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

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

相关文章

Opencv轮廓检测运用与理解

目录 引入 基本理解 加深理解 ①比如我们可以获取我们的第一个轮廓,只展示第一个轮廓 ②我们还可以用一个矩形把我们的轮廓给框出来 ③计算轮廓的周长和面积 引入 顾名思义,就是把我们图片的轮廓全部都描边出来 也就是我们在日常生活中面部识别的时候会有一个框,那玩意就…

华南理工大学数字信号处理实验实验二源码(薛y老师)

一、实验目的 ▪ 综合运用数字信号处理的理论知识进行信号分析并利用MATLAB作为编程工具进行计算机实现&#xff0c;从而加 深对所学知识的理解&#xff0c;建立概念。 ▪ 掌握数字信号处理的基本概念、基本理论和基本方法。 ▪ 学会用MATLAB对信号进行分析和处理。 ▪ 用F…

PS滤镜插件:Adobe Camera Raw 16 for Mac中文激活版

Adobe Camera Raw是Adobe公司开发的一款用于处理数码相机RAW格式文件的软件插件。它可以在Adobe Photoshop、Adobe Bridge和Adobe Lightroom等软件中使用&#xff0c;用于调整RAW文件的曝光、白平衡、对比度、色彩饱和度、锐化等参数&#xff0c;从而得到更好的图像质量。 软件…

python批量复制图片到execl并指定图片的大小

工作需要需要复制批量图片到execl&#xff0c;并指定大小&#xff0c;这里简单实现一下&#xff0c;使用xlwings库来实现总体来说是比较简单的&#xff0c;这里简单记录一下 import xlwings as xw import os# 创建一个可见的Excel应用程序对象 app xw.App(visibleTrue)# 打开…

idea远程服务调试

1. 配置idea远程服务调试 这里以 idea 新 ui 为例&#xff0c;首先点击上面的 debug 旁边的三个小圆点&#xff0c;然后在弹出的框框中选择 “Edit”&#xff0c;如下图所示。 然后进入到打开的界面后&#xff0c;点击左上角的 “” 进行添加&#xff0c;找到 “Remote JVM De…

XSS漏洞:一道关于DOM型XSS的题目

目录 解法1&#xff1a;SVG标签 DOM树的构建 img标签没有执行成功原因 svg标签执行成功的原因 总结 解法2&#xff1a;details标签 事件触发流程 总结 解法3&#xff1a;Dom-Clobbring 一个简单的例子来了解DOM劫持 toString 解决问题 xss系列往期文章&#xff1a; …

VC++中使用OpenCV进行形状和轮廓检测

VC中使用OpenCV进行形状和轮廓检测 在VC中使用OpenCV进行形状和轮廓检测&#xff0c;轮廓是形状分析以及物体检测和识别的有用工具。如下面的图像中Shapes.png中有三角形、矩形、正方形、圆形等&#xff0c;我们如何去区分不同的形状&#xff0c;并且根据轮廓进行检测呢&#…

初识React,基础(1), 安装react,jsx文件,类组件和函数组件,css样式

第一部分:初识react react: 用于构建用户界面的 JavaScript 库全局安装,win r, 命令: npm install create-react-app -g3. 创建一个react应用, 这里我在vscode 里面创建, 创建之后,运行 create-react-app my-appcd my-app npm start 第二部分: redact 组件定义以及使用 rea…

当 OpenTelemetry 遇上阿里云 Prometheus

作者&#xff1a;逸陵 背景 在云原生可观测蓬勃发展的当下&#xff0c;想必大家对 OpenTelemetry & Prometheus 并不是太陌生。OpenTelemetry 是 CNCF&#xff08;Cloud Native Computing Foundation&#xff09;旗下的开源项目&#xff0c;它的目标是在云原生时代成为应…

【Unity学习笔记】New Input System 部分源码和测试用例补充

转载请注明出处&#xff1a;&#x1f517;https://blog.csdn.net/weixin_44013533/article/details/135630016 作者&#xff1a;CSDN|Ringleader| 主要参考&#xff1a; Unity官方Input System手册与API【Unity学习笔记】Unity TestRunner使用【Unity学习笔记】第十二 New Inp…

MySQL的执行流程

一、MySQL的执行流程 MySQL架构分为Server层、存储引擎&#xff0c;其中Server层又分为连接器、查询缓存、分析器、优化器执行器五个部分。当客户端发送请求后依次需要经过 处理请求、查询缓存、语法解析、查询优化、存储引擎部分。 1. 连接器 负责维持和管理连接&#xff…

【差分数组】【图论】【分类讨论】【整除以2】100213按距离统计房屋对数目

作者推荐 【动态规划】【数学】【C算法】18赛车 本文涉及知识点 差分数组 图论 分类讨论 整除以2 LeetCode100213按距离统计房屋对数目 给你三个 正整数 n 、x 和 y 。 在城市中&#xff0c;存在编号从 1 到 n 的房屋&#xff0c;由 n 条街道相连。对所有 1 < i < n…

Java代码审计Shiro反序列化CB1链source入口sink执行gadget链

目录 0x00 前言 0x01 CC链&CB链简介 1. Commons Collections链是什么&#xff1f; 2. Commons BeanUtils链是什么&#xff1f; 0x02 测试Commons BeanUtils1链 0x03 Shiro550 - Commons BeanUtils1链 - 跟踪分析&#xff08;无依赖&#xff09; 1. 前置知识 2. Co…

Node开发基础

1. 概述 1.1 为什么要学习服务器端开发基础 能够和后端程序员更加紧密的配合 网站业务逻辑前置&#xff0c;学习前端技术需要后端技术支撑 扩宽知识视野&#xff0c;能够站在更高的角度审视整个项目 1.2 服务器端开发要做的事情 实现网站的业务逻辑 ---网站登录部分&#…

矩阵重叠问题判断

创作背景 看到一道题目有感而发想写一篇题解&#xff0c;涉及的是一种逆向思维 桌面窗体重叠 - 洛谷https://www.luogu.com.cn/problem/U399827题目来源于《信息学奥赛课课通》 大致就是给一个长方形的左上顶点坐标&#xff08;x1,y1&#xff09;和右下顶点坐标&#xff08;x…

【设计模式】适配器和桥接器模式有什么区别?

今天我探讨一下适配器模式和桥接模式&#xff0c;这两种模式往往容易被混淆&#xff0c;我们希望通过比较他们的区别和联系&#xff0c;能够让大家有更清晰的认识。 适配器模式&#xff1a;连接不兼容接口 当你有一个类的接口不兼容你的系统&#xff0c;而你又不希望修改这个…

云服务器定价_云服务器价格_云主机计费模式_腾讯云

腾讯云服务器租用价格表&#xff1a;轻量应用服务器2核2G3M价格62元一年、2核2G4M价格118元一年&#xff0c;540元三年、2核4G5M带宽218元一年&#xff0c;2核4G5M带宽756元三年、轻量4核8G12M服务器446元一年、646元15个月&#xff0c;云服务器CVM S5实例2核2G配置280.8元一年…

嵌入式培训机构四个月实训课程笔记(完整版)-C++和QT编程第六天-Qt UDP编程(物联技术666)

链接&#xff1a;https://pan.baidu.com/s/1-u7GvgM0TLuiy9z7LYQ80Q?pwd1688 提取码&#xff1a;1688 在Qt中提供了QUdpSocket 类来进行UDP数据报&#xff08;datagrams&#xff09;的发送和接收。这里我们还要了解一个名词Socket&#xff0c;也就是常说的“套接字”。 Qt 网络…

强化学习(四)动态规划——1

动态规划算法&#xff08;DP&#xff09;&#xff1a;在马尔可夫决策过程&#xff08;MDP&#xff09;的完美环境模型下计算最优策略。但其在强化学习中实用性有限&#xff0c;其一是它是基于环境模型已知&#xff1b;其二是它的计算成本很大。但它在理论伤仍然很重要&#xff…