网络编程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)# 打开…

Vue与React:核心异同点解析

Vue和React是前端开发领域的两大主流框架&#xff0c;它们在核心概念、特性和应用场景上存在一些异同点。本文将深入探讨Vue和React的核心异同点&#xff0c;帮助读者更好地理解两者的关系和差异。 一、引言 在前端开发的道路上&#xff0c;Vue和React两大框架的争论一直存在…

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; …

大语言模型无代码构建知识图谱(1)--提示工程准备

2023年3月15日&#xff0c;ChatGPT4.0的横空出世&#xff0c;将人们对大语言模型的关注推到了风口浪尖。由于其在智能问答、翻译以及文本生成等工作任务上的卓越表现&#xff0c;业界一度出现了不再需要发展知识图谱相关技术的观点&#xff0c;知识图谱相关概念严重受挫。无可置…

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

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

制作linux运行包

从源码制作 syslinux:https://mirrors.edge.kernel.org/pub/linux/utils/boot/syslinux/syslinux-6.03.tar.gz busybox:https://busybox.net/downloads/busybox-1.26.0.tar.bz2 kernel:https://mirrors.edge.kernel.org/pub/linux/kernel/v6.x/linux-6.5.7.tar.gz 遇到问题&…

初识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…

Apache-iotdb物联网数据库的安装及使用

一、简介 >Apache IoTDB (Database for Internet of Things) is an IoT native database with high performance for data management and analysis, deployable on the edge and the cloud. Due to its light-weight architecture, high performance and rich feature set…

爬虫工作量由小到大的思维转变---<第三十七章 Scrapy redis里面的key >

前言: 终于找到机会,开始把scrapy-redis细致地给大伙通一通了! 为什么非要细致讲scrapy-redis呢? 1.市面上关于scrapy-redis的教程,都比较笼统; demo级别好写,但是一旦上了项目,就问题百出!2.scrapy-redis里面的思路,其实跟单个爬虫或者集合式爬虫他的思路有点不一样; 正文…

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 服务器端开发要做的事情 实现网站的业务逻辑 ---网站登录部分&#…