基于UDP实现直播间聊天的功能

需求:软件划分为用户客户端和主播服务端两个软件client.c和server.c 用户客户端负责:1.接收用户的昵称2.接收用户输入的信息,能够将信息发送给服务端3.接收服务端回复的数据信息,并完成显示主播服务端负责:1.对所有加入直播间的用户的IP地址和端口实现管理(加入、退出)2.当有新的客户端加入时,能够向所有客户端提示:"欢迎 XXX 用户进入直播间"3.当有客户端退出时,能够向所有客户端提示:"XXX 离开直播间"4.能够实现客户端聊天内容的转发,当某个客户端发送聊天信息时,能够将该信息转给除了该用户之外聊天室内所有其余客户端用户

head.h文件

#ifndef __HEAD_H__
#define __HEAD_H__#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <dirent.h>
#include <time.h>
#include <pwd.h>
#include <grp.h>
#include <pthread.h>
#include <semaphore.h>
#include <signal.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/ip.h>
#include <netinet/in.h>struct address
{int mark;struct sockaddr_in addr;
};struct msgbuf{int type;char name[32];char text[512];
};#define MSG_TYPE_START		100
#define MSG_TYPE_END		200
#define MSG_TYPE_CHAT		300
#define RECV_ADDR			"192.168.1.152"
#define RECV_PORT			50000#endif

client.c

#include "head.h"char name[32] = {0};
int sockfd = 0;
struct sockaddr_in recvaddr;
pthread_t tid_send;		//发线程
pthread_t tid_recv;		//收线程void *sendfun(void *arg)
{struct msgbuf sendmsg;	ssize_t nsize = 0;while (1){memset(&sendmsg, 0, sizeof(sendmsg));sendmsg.type = MSG_TYPE_CHAT;sprintf(sendmsg.name, "%s", name);gets(sendmsg.text);if (!strcmp(sendmsg.text, ".quit")){sendmsg.type = MSG_TYPE_END;}nsize = sendto(sockfd, &sendmsg, sizeof(sendmsg), 0, (struct sockaddr *)&recvaddr, sizeof(recvaddr));if (-1 == nsize){perror("fail to sendto");return NULL;}if (sendmsg.type == MSG_TYPE_END){break;}}pthread_cancel(tid_recv);return NULL;
}void *recvfun(void *arg)
{struct msgbuf recvmsg;ssize_t nsize = 0;while (1){memset(&recvmsg, 0, sizeof(recvmsg));nsize = recvfrom(sockfd, &recvmsg, sizeof(recvmsg), 0, NULL, NULL);if (-1 == nsize){perror("fail to recvfrom");return NULL;}if (recvmsg.type == MSG_TYPE_CHAT){printf("%s(%s:%d)>%s\n", recvmsg.name, RECV_ADDR, RECV_PORT, recvmsg.text);}else if (recvmsg.type == MSG_TYPE_END){break;}}pthread_cancel(tid_send);return NULL;
}int main(void)
{struct msgbuf sendmsg;ssize_t nsize = 0;recvaddr.sin_family = AF_INET;recvaddr.sin_port = htons(RECV_PORT);recvaddr.sin_addr.s_addr = inet_addr(RECV_ADDR);printf("请输入您的昵称:\n");gets(name);sockfd = socket(AF_INET, SOCK_DGRAM, 0);if (-1 == sockfd){perror("fail to socket");return -1;}memset(&sendmsg, 0, sizeof(sendmsg));sendmsg.type = MSG_TYPE_START;sprintf(sendmsg.name, "%s", name);nsize = sendto(sockfd, &sendmsg, sizeof(sendmsg), 0, (struct sockaddr *)&recvaddr, sizeof(recvaddr));if (-1 == nsize){perror("fail to sendto");return -1;}pthread_create(&tid_send, NULL, sendfun, NULL);pthread_create(&tid_recv, NULL, recvfun, NULL);pthread_join(tid_send, NULL);pthread_join(tid_recv, NULL);close(sockfd);return 0;
}

server.c

#include "head.h"struct address ClientIpList[100];int AddClientIp(struct sockaddr_in TmpAddr)
{int i = 0;for(i = 0;i < 100;++i){if(ClientIpList[i].mark == 0){ClientIpList[i].addr = TmpAddr;ClientIpList[i].mark = 1;break;}}return 0;
}
int DelClientIp(struct sockaddr_in TmpAddr)
{int i = 0;for(i = 0;i < 100;++i){if(0 == memcmp(&TmpAddr,&ClientIpList[i].addr,sizeof(TmpAddr))){ClientIpList[i].mark = 0;break;}}return 0;
}int BoardcastClientIp(int sockfd,struct sockaddr_in TmpAddr,struct msgbuf TmpMes)
{int i = 0;ssize_t nsize = 0;for(i = 0;i < 100;++i){if(ClientIpList[i].mark == 0){continue;}if(0 != memcmp(&TmpAddr,&ClientIpList[i].addr,sizeof(TmpAddr))){nsize = sendto(sockfd,&TmpMes,sizeof(TmpMes),0,(struct sockaddr *)&ClientIpList[i].addr,sizeof(ClientIpList[i].addr));if(-1 == nsize){continue;}}}return 0;
}int main(void)
{int sockfd = 0;int ret = 0;ssize_t nsize = 0;struct msgbuf recvmes;struct sockaddr_in recvaddr;struct sockaddr_in sendaddr;socklen_t addrlen = sizeof(sendaddr);recvaddr.sin_family = AF_INET;recvaddr.sin_port = htons(RECV_PORT);recvaddr.sin_addr.s_addr = INADDR_ANY;sockfd = socket(AF_INET, SOCK_DGRAM, 0);if (-1 == sockfd){perror("fail to socket");return -1;}ret = bind(sockfd, (struct sockaddr *)&recvaddr, sizeof(recvaddr));if (-1 == ret){perror("fail to bind");return -1;}memset(&ClientIpList,0,sizeof(ClientIpList));while (1){memset(&recvmes, 0, sizeof(recvmes));nsize = recvfrom(sockfd, &recvmes, sizeof(recvmes), 0,(struct sockaddr *)&sendaddr, &addrlen);if (-1 == nsize){perror("fail to recvfrom");return -1;}if(recvmes.type == MSG_TYPE_START){AddClientIp(sendaddr);recvmes.type = MSG_TYPE_CHAT;sprintf(recvmes.text,"%s",recvmes.name);}else if (recvmes.type == MSG_TYPE_END){DelClientIp(sendaddr);recvmes.type = MSG_TYPE_CHAT;sprintf(recvmes.text,"%s",recvmes.name);}if (recvmes.type == MSG_TYPE_CHAT){BoardcastClientIp(sockfd,sendaddr,recvmes);}}close(sockfd);return 0;
}

结果:

在这里插入图片描述

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

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

相关文章

pytorch(四、五)用pytorch实现线性回归和逻辑斯蒂回归(分类)

文章目录 线性回归代码过程准备数据设计模型设计构造函数与优化器训练过程训练代码和结果pytorch中的Linear层的底层原理&#xff08;个人喜欢&#xff0c;不用看&#xff09;普通矩阵乘法实现Linear层实现 回调机制 逻辑斯蒂回归模型损失函数代码和结果 线性回归 代码过程 训…

一键清除JavaScript代码中的注释:使用正则表达式实现

这个正则表达式可以有效地匹配 JavaScript 代码中的各种注释&#xff0c;并且跳过了以 http: 或 https: 开头的链接。 /\/\*[\s\S]*?\*\/|\/\/[^\n]*|<!--[\s\S]*?-->|(?<!http:|https:)\/\/[^\n]*/gvscode 实战&#xff0c;ctrlF 调出查找替换工具&#xff0c;点…

(五)关系数据库标准语言SQL

注&#xff1a;课堂讲义使用的数据库 5.1利用SQL语言建立数据库 5.1.1 create Database 5.1.2 create schema...authorization... 创建数据库和创建模式的区别&#xff1a; 数据库是架构的集合&#xff0c;架构是表的集合。但在MySQL中&#xff0c;他们使用的方式是相同的。 …

设计模式学习笔记(二):工厂方法模式

一、定义 工厂方法模式&#xff08;Factory Method Pattern&#xff09;是一种创建型设计模式&#xff0c;它提供了一种在不指定具体类的情况下创建对象的方法。工厂方法模式定义了一个用于创建对象的接口&#xff0c;让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟…

maven项目结构管理统一项目配置操作

一、maven分模块开发 Maven 分模块开发 1.先创建父工程&#xff0c;pom.xml文件中&#xff0c;打包方式为pom 2.然后里面有许多子工程 3.我要对父工程的maven对所有子工程进行操作 二、解读maven的结构 1.模块1 <groupId>org.TS</groupId><artifactId>TruthS…

Dubbo基础入门二

8、Dubbo协议 服务调用 8.1 服务端 启动过程深入分析 我们查看一下服务启动的过程 ProtocolFilterWrapper.export 好我们进入DubboProtocol.export 创建服务 分析我们的Handler 我们接着返回刚才位置 下面的super方法里面会创建服务&#xff0c;ChannelHandlers.wrap会对hand…

19-Java中介者模式 ( Mediator Pattern )

Java中介者模式 摘要实现范例 中介者模式&#xff08;Mediator Pattern&#xff09;提供了一个中介类&#xff0c;该类通常处理不同类之间的通信&#xff0c;并支持松耦合&#xff0c;使代码易于维护中介者模式是用来降低多个对象和类之间的通信复杂性中介者模式属于行为型模式…

每周一算法:A*(A Star)算法

八数码难题 题目描述 在 3 3 3\times 3 33 的棋盘上&#xff0c;摆有八个棋子&#xff0c;每个棋子上标有 1 1 1 至 8 8 8 的某一数字。棋盘中留有一个空格&#xff0c;空格用 0 0 0 来表示。空格周围的棋子可以移到空格中。要求解的问题是&#xff1a;给出一种初始布局…

【RT-DETR有效改进】全新的SOATA轻量化下采样操作ADown(轻量又涨点,附手撕结构图)

一、本文介绍 本文给大家带来的改进机制是利用2024/02/21号最新发布的YOLOv9其中提出的ADown模块来改进我们的Conv模块,其中YOLOv9针对于这个模块并没有介绍,只是在其项目文件中用到了,我将其整理出来用于我们的RT-DETR的项目,经过实验我发现该卷积模块(作为下采样模块)…

nicegui学习使用

https://www.douyin.com/shipin/7283814177230178363 python轻量级高自由度web框架 - NiceGUI (6) - 知乎 python做界面&#xff0c;为什么我会强烈推荐nicegui 秒杀官方实现&#xff0c;python界面库&#xff0c;去掉90%事件代码的nicegui python web GUI框架-NiceGUI 教程…

嵌入式学习第二十五天!(网络的概念、UDP编程)

网络&#xff1a; 可以用来&#xff1a;数据传输、数据共享 1. 网络协议模型&#xff1a; 1. OSI协议模型&#xff1a; 应用层实际收发的数据表示层发送的数据是否加密会话层是否建立会话连接传输层数据传输的方式&#xff08;数据包&#xff0c;流式&#xff09;网络层数据的…

吴恩达深度学习笔记:神经网络的编程基础2.1-2.3

目录 第一门课&#xff1a;神经网络和深度学习 (Neural Networks and Deep Learning)第二周&#xff1a;神经网络的编程基础 (Basics of Neural Network programming)2.1 二分类(Binary Classification)2.2 逻辑回归(Logistic Regression) 第一门课&#xff1a;神经网络和深度学…

基于YOLOv5的无人机视角水稻杂草识别检测

&#x1f4a1;&#x1f4a1;&#x1f4a1;本文主要内容:详细介绍了无人机视角水稻杂草识别检测整个过程&#xff0c;从数据集到训练模型到结果可视化分析。 博主简介 AI小怪兽&#xff0c;YOLO骨灰级玩家&#xff0c;1&#xff09;YOLOv5、v7、v8优化创新&#xff0c;轻松涨点…

Github 2024-03-08 Java开源项目日报 Top10

根据Github Trendings的统计,今日(2024-03-08统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Java项目9C++项目1非开发语言项目1《Hello 算法》:动画图解、一键运行的数据结构与算法教程 创建周期:476 天协议类型:OtherStar数量:63556…

网络原理初识(2)

目录 一、协议分层 1、分层的作用 2、OSI七层模型 3、TCP / IP五层&#xff08;或四层&#xff09;模型 4、网络设备所在分层 5、网络分层对应 二、封装和分用 发送过程&#xff08;封装&#xff09; 1、应用层(应用程序) QQ 2、输入层 3、网络层 4、数据链路层 5、物理…

金融行业专题|基金超融合架构转型与场景探索合集(2023版)

更新内容 更新 SmartX 超融合在基金行业的覆盖范围、部署规模与应用场景。更新信创云资源池、关键业务系统性能优化等场景实践。更多超融合金融核心生产业务场景实践&#xff0c;欢迎下载阅读电子书《金融核心生产业务场景探索文章合集》。 随着数字化经济的蓬勃发展&#xf…

记一次Flink任务无限期INITIALIZING排查过程

1.前言 环境&#xff1a;Flink-1.16.1&#xff0c;部署模式&#xff1a;Flink On YARN&#xff0c;现象&#xff1a;Flink程序能正常提交到 YARN&#xff0c;Job状态是 RUNNING&#xff0c;而 Task状态一直处于 INITIALIZING&#xff0c;如下图&#xff1a; 通过界面可以看到…

ue4.27 发现 getRandomReachedLocation 返回 false

把这个玩意儿删掉&#xff0c;重启工程&#xff0c;即可 如果还不行 保证运动物体在 volum 内部&#xff0c;也就是绿色范围内确保 project setting 里面的 navigation system 中 auto create navigation data 是打开的(看到过博客说关掉&#xff0c;不知道为啥) 如果还不行&…

智奇科技工业 Linux 屏更新开机logo

智奇科技工业 Linux 屏更新开机logo 简介制作logo.img文件1、转换格式得到logo.bmp2、使用Linux命令生成img文件 制作rootfs.img文件替换rootfs.img中的logo 生成update.img固件附件 简介 智奇科技的 Linux 屏刷开机logo必须刷img镜像文件&#xff0c;比较复杂。 制作logo.i…

深入浅出(二)MVVM

MVVM 1. 简介2. 示例 1. 简介 2. 示例 示例下载地址&#xff1a;https://download.csdn.net/download/qq_43572400/88925141 创建C# WPF应用(.NET Framework)工程&#xff0c;WpfApp1 添加程序集 GalaSoft.MvvmLight 创建ViewModel文件夹&#xff0c;并创建MainWindowV…