基于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.mzph.cn/news/729150.shtml

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

相关文章

网络协议栈--应用层--HTTPS协议

目录 一、HTTPS协议原理1.1 HTTPS协议是什么&#xff1f;1.2 概念准备1.2.1 什么是“加密”&#xff1f;1.2.2 为什么要加密&#xff1f;1.2.3 常见的加密方式1.2.3.1 对称加密1.2.3.2 非对称加密 1.2.4 数据摘要&&数据指纹1.2.5 数字签名1.2.6 理解链-承上启下 1.3 HT…

关于JVM的小总结(待补充)

JVM组成及他们之间的关系 装载类子系统字节码执行引擎运行时数据区 装载类子系统 类加载器字节码调节器类加载运行时数据区 字节码执行引擎 运行时数据区 线程私有 虚拟机栈本地方法栈程序计数器 线程共享 堆方法区&#xff08;元空间&#xff09;

后见之明!错过6个涨停板之后的复盘

在今年1月2日和1月3日&#xff0c;旅游板块两支个股先后涨停&#xff0c;此后一支月内三倍&#xff0c;另一支连续6个涨停。事后复盘&#xff0c;我们如何在1月2日第一支个股涨停之后&#xff0c;通过量化分析&#xff0c;找出第二支股&#xff1f; 一个3倍&#xff0c;一个6连…

M1电脑 Xcode15升级遇到的问题

遇到四个问题 一、模拟器下载经常报错。 二、Xcode15报错: SDK does not contain libarclite 三、报错coreAudioTypes not found 四、xcode模拟器运行一次下次必定死机 一、模拟器下载经常报错。 可以https://developer.apple.com/download/all/?qios 下载最新的模拟器&…

工业制氧机的使用与维护管理指南

工业制氧机是工业生产中不可或缺的重要设备&#xff0c;其高效稳定的供氧功能对于保障生产过程的顺利进行至关重要。为了确保工业制氧机能够持续高效地提供氧气&#xff0c;正确的使用方法和维护措施是必不可少的。 在使用工业制氧机时&#xff0c;我们首先要确保设备放置在通风…

网络聊天室的UDP实现以及数据库

网络聊天室UDP实现 服务器端&#xff1a; 头文件&#xff1a; #include <myhead.h>//定义客户信息结构体 typedef struct magtye {char type; //消息类型char name[100]; //客户姓名char text[1024]; //客户发送聊天信息 }msg_t;//定义结构体存储…

mysql的语法总结2

命令&#xff1a; mysql -u 用户名 -p mysql登录 命令&#xff1a;create database u1 创建数据库u1 查询数据库 使用数据库u1 创建表department 查询表department ALTER TABLE 表名 操作类型&#xff1b; 操作类型可以有以下的操作&#xff1a; 添加列&#x…

CubeMX使用教程(2)——点亮LED

在上一章&#xff0c;我们完成了CubeMX的环境配置&#xff0c;这一章我们通过CubeMX来完成点亮LED的工作。 通过LED原理图可知&#xff0c;如果我们要点亮LD1&#xff08;第一个灯&#xff09;&#xff0c;它对应开发板的PC8端口&#xff0c;因此我们应该在CubeMX中将PC8配置为…

【并查集】一种简单而强大高效的数据结构

目录 一、并查集原理 二、并查集实现 三、并查集应用 1. LeetCode并查集相关OJ题 2. 并查集的其他应用及总结 一、并查集原理 并查集&#xff08;Disjoint Set&#xff09;是一种用来管理元素分组和查找元素所属组别的数据结构。它主要支持两种操作&#xff1a;查找&…

JavaScript进阶 (1)

封装 构造函数存在问题 js可以通过构造函数进行封装&#xff0c;但存在浪费内存问题 每创建新的对象引用数据类型就开辟新的空间 原型 构造函数通过原型分配函数是所有对象所共享的 每一个构造函数都有一个prototype属性&#xff0c;指向另一个对象&#xff0c;也称为原型…

小型内衣裤洗衣机哪个牌子好?四款高热度内衣洗衣机力荐

相信很多用户从小就有个观念&#xff0c;内衣裤不能跟其他衣物一起混合洗&#xff0c;否则会感染细菌&#xff0c;所以不少人的内衣裤一直都是自己手洗的&#xff0c;清洗内衣裤不算麻烦&#xff0c;但日常都要换洗&#xff0c;对一个白天上班已经很累的人来说&#xff0c;真是…

如何 借助 AI + bat,1分钟内建立100个自定义文件和文件夹?

01 你好&#xff0c;我是云桃桃。 最近&#xff0c;我在写web系列的知识&#xff0c;做的过程中遇到过不少问题。今天&#xff0c;就来说说&#xff0c;我解决的一个批量新建文件/文件夹的问题。 事情是这样的。首先&#xff0c;我的大纲基本在幕布里已经弄好了&#xff0c;…

简析内部审计数字化转型的方法和路径【小落送书(第6期)】

个人名片&#xff1a; &#x1f43c;作者简介&#xff1a;一名大三在校生&#xff0c;喜欢AI编程&#x1f38b; &#x1f43b;‍❄️个人主页&#x1f947;&#xff1a;落798. &#x1f43c;个人WeChat&#xff1a;hmmwx53 &#x1f54a;️系列专栏&#xff1a;&#x1f5bc;️…

基于ACM32 MCU的电动滑板车方案介绍

随着智能科技的快速发展&#xff0c;电动滑板车的驱动系统也得到了长足的发展。国内外的电动滑板车用电机驱动系统分为传统刷式电机和无刷电机两种类型。其中&#xff0c;传统的刷式电机已经逐渐被无刷电机所取代&#xff0c;无刷电机的性能和寿命都更出色&#xff0c;已成为电…

玩转AI大模型应用开发,轻松打造热门APPai数字人直播软件!

AI大模型应用在数字人直播领域的应用愈发成熟&#xff0c;为开发者提供了更多创意和可能性。数字人直播软件是当前热门的应用之一&#xff0c;它结合了虚拟主播和人工智能技术&#xff0c;为用户带来全新的互动体验。想要打造一个火爆的数字人直播软件&#xff0c;就需要玩转AI…

从0到1快速搭建一个jeecg 企业级应用管理后台

一. 基本介绍 官网地址&#xff1a;https://jeecg.com/ JeecgBoot 是一款企业级的低代码平台&#xff01;前后端分离架构 SpringBoot2.x&#xff0c;SpringCloud&#xff0c;Ant Design&Vue3&#xff0c;Mybatis-plus&#xff0c;Shiro&#xff0c;JWT 支持微服务。强大的…

vue 使用谷歌地图 @googlemaps/js-api-loader 进行模糊搜索

<template><div class"map"><div class"mapLeftStyle"><el-inputv-model"input"placeholder"请输入内容"class"controls"input"chnageinput"><i slot"prefix" class"e…

JavaWeb-MyBatis(上)

学完项目管理工具Maven后&#xff0c;继续学习MyBatis。我们都知道&#xff0c;JDBC是一个与数据库连接相关的API&#xff0c;最开始学习数据库连接都是从JDBC开始学起&#xff0c;但是其也有缺点&#xff0c;比如硬编码和操作繁琐等等。而今天学习的MyBatis就是专门为简化JDBC…

免费SSL证书整理合集

有哪些免费的SSL证书呢&#xff1f;下面整理了一下非常有性价比的 一&#xff1a;免费单域名SSL证书&#xff1a;适用于只有一个域名的情况下使用 点击申请免费单域名SSL证书https://www.joyssl.com/certificate/select/joyssl-dv-single-free.html?nid7 二&#xff1a;通配…

基于单片机的篮球计分器设计

在当今的体育赛事中,比赛的计分系统对观众和运动员尤为重要,观众可以根据比分的实时显示为自己支持的队伍呐喊助威,运动员更是要靠着计分器来把握比赛的节奏,包括攻防转换、替补换人以及赛间休息等等。因此,为了让比赛进行得更加专业化和流畅化,我们有必要对比赛的计分系…