并发聊天服务器编写

并发聊天服务器

在这里插入图片描述

package mainimport ("fmt""net""strings""time"
)// 结构体
type Client struct {C    chan string //用户发送数据的管道Name string      //用户名Addr string      //网络地址
}// 保存在线用户 cliAddr -->client
var onlineMap map[string]Client// 创建一个通信的管道
var message = make(chan string)func MakeMsg(cli Client, msg string) (buf string) {buf = "[" + cli.Addr + "]" + cli.Name + ": " + msgreturn
}// WriteMsgToClient 专门给当前客户端发送信息
func WriteMsgToClient(cli Client, conn net.Conn) {for msg := range cli.C { //给当前客户端发送信息_, err := conn.Write([]byte(msg + "\n"))if err != nil {fmt.Println("conn write err =", err)return}}
}// HandleConn //处理用户链接
func HandleConn(conn net.Conn) {defer conn.Close()//获取客户端的网络地址cliAddr := conn.RemoteAddr().String()//创建一个结构体 创建一个管道 默认用户名和网络地址一样cli := Client{make(chan string), cliAddr, cliAddr}//把结构体添加到maponlineMap[cliAddr] = cli//新开一个协程,专门给当前客户端发送信息go WriteMsgToClient(cli, conn)//广播某个人在线//message <- "[" + cli.Addr + "]" + cli.Name + ": login"message <- MakeMsg(cli, "login")//提示,我是谁cli.C <- MakeMsg(cli, "I am hello")isQuit := make(chan bool) //对方是否主动退出isData := make(chan bool) //对方是否有数据发送//新建一个协程,接收用户发送过来的数据go func() {buf := make([]byte, 2048)for {readSize, err := conn.Read(buf)//if err != nil {//	if err == io.EOF {//		fmt.Println("写入完毕")//	}//	return//}if readSize == 0 { //对象断开,或者出问题isQuit <- truefmt.Println("conn read err = ", err)return}msg := string(buf[:readSize-1])if len(msg) == 3 && msg == "who" { //查询在线用户//遍历map,get当前用户发送所有成员conn.Write([]byte("user list:\n"))for _, tmp := range onlineMap {msg = tmp.Addr + ":" + tmp.Name + "\n"conn.Write([]byte(msg))}} else if len(msg) >= 8 && msg[:6] == "rename" {//修改用户名name := strings.Split(msg, "|")[1]cli.Name = nameonlineMap[cliAddr] = cliconn.Write([]byte("rename ok\n"))} else {//转发此内容fmt.Println("成朋")message <- MakeMsg(cli, msg)}isData <- true //代表有数据}}()for true {//通过select检测channel的流动select {case <-isQuit:delete(onlineMap, cliAddr)           //当前用户从map移除message <- MakeMsg(cli, "login out") //广播谁下线了returncase <-isData:case <-time.After(30 * time.Second):delete(onlineMap, cliAddr)message <- MakeMsg(cli, "time out leave out") //超时了return}}}// Manager 新开一个协程 转发消息,只要有消息来了,遍历map,给map每个成员都发送消息
func Manager() {//给map分配空间onlineMap = make(map[string]Client)for true {meg := <-message //没有消息前,这里会阻塞//遍历map,给map每个成员都发送消息for _, client := range onlineMap {client.C <- meg //把消息给这个管道}}
}
func main() {//监听listener, err := net.Listen("tcp", ":8000")if err != nil {fmt.Println("listener err = ", err)return}defer listener.Close()//新开一个协程 转发消息,只要有消息来了,遍历map,给map每个成员都发送消息go Manager()//主协程。循环阻塞等待用户连接for true {conn, err := listener.Accept() //建立连接if err != nil {fmt.Println("conn err = ", err)continue}go HandleConn(conn) //处理用户链接}
}

调试工具netcat

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

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

相关文章

DAY07_Maven高级——分模块开发与设计依赖管理聚合与继承属性管理多环境配置与应用私服

目录 一 分模块开发与设计1. 分模块开发的意义问题导入模块拆分原则 2. 分模块开发问题导入2.1 创建Maven模块2.2 书写模块代码2.3 通过maven指令安装模块到本地仓库&#xff08;install指令&#xff09; 二 依赖管理1. 依赖传递问题导入 2. 可选依赖问题导入 3. 排除依赖问题导…

大数据技术之Hadoop:Yarn集群部署(七)

目录 一、部署说明 二、集群规划 三、开始配置 3.1 MapReduce配置文件 3.2 YARN配置文件 3.3 分发配置文件 四、集群启停 4.1 命令介绍 4.2 演示 4.3 查看YARN的WEB UI页面 一、部署说明 Hadoop HDFS分布式文件系统&#xff0c;我们会启动&#xff1a; NameNode进…

三维模型3DTile格式轻量化压缩处理效率提高的技术方浅析

三维模型3DTile格式轻量化压缩处理效率提高的技术方浅析 随着三维模型在各个领域的广泛应用&#xff0c;对于其格式的轻量化压缩处理和效率提高的需求也越发迫切。本文将介绍一些技术方法&#xff0c;帮助实现三维模型3DTile格式的轻量化压缩处理并提高处理效率。 首先&#x…

怎么压缩pdf文件大小?详细压缩步骤

怎么压缩pdf文件大小&#xff1f;在日常的工作和学习中&#xff0c;我们频繁地处理PDF文件。然而&#xff0c;有时候这些文件的大小可能会非常庞大&#xff0c;这给我们带来了一系列的问题。首先&#xff0c;它们占用了大量的存储空间&#xff0c;使得我们的设备变得拥挤不堪。…

蓝天转债,双良转债上市价格预测

蓝天转债111017 基本信息 转债名称&#xff1a;蓝天转债&#xff0c;评级&#xff1a;AA&#xff0c;发行规模&#xff1a;8.7亿元。 正股名称&#xff1a;蓝天燃气&#xff0c;今日收盘价&#xff1a;9.74元&#xff0c;转股价格&#xff1a;10.13元。 当前转股价值 转债面值…

Purple Pi OH(Debian/Ubuntu)使用python控制gpio

本文分享的是Purple Pi OH开源主板搭载Debian/Ubuntu系统如何使用python控制gpio。 Purple Pi OH作为一款兼容树莓派的开源主板&#xff0c;采用瑞芯微RK3566 (Cortex-A55) 四核64位超强CPU,主频最高达1.8 GHz,算力高达1Tops&#xff0c;支持INT8/INT16&#xff0c;支持Tensor…

输入验证在防止安全漏洞方面的重要性

在当今快速发展的数字环境中&#xff0c;技术推动创新和便利&#xff0c;确保我们数字资产的安全仍然是一个关键问题。创建强大的应用程序安全性的核心在于输入验证的基本且最重要的概念。 在这篇博文中&#xff0c;我们将介绍输​​入验证的重要性及其对加强我们的数字防御以…

Window安装Node.js npm appium Appium Desktop

Window安装Node.js npm appium appium Desktop 1.安装nodejs 参考链接&#xff1a; https://blog.csdn.net/weixin_42064877/article/details/131610918 1)打开浏览器&#xff0c;并前往 Node.js 官网 https://nodejs.org/ ↗。 2)在首页中&#xff0c;您可以看到当前 Node.…

超高清Mac动态壁纸桌面:Dynamic Wallpaper for Mac中文版本

Dynamic Wallpaper for Mac是一款引人注目的动态壁纸软件&#xff0c;为你的Mac桌面带来全新的视觉体验。 [特点1]&#xff1a;轻松定制动态壁纸&#xff1a;这款软件具有用户友好的界面&#xff0c;使得定制动态壁纸变得异常简单。用户可以轻松选择和调整动画效果&#xff0c…

读书笔记:多Transformer的双向编码器表示法(Bert)-1

多Transformer的双向编码器表示法 Bidirectional Encoder Representations from Transformers&#xff0c;即Bert&#xff1b; 本笔记主要是对谷歌Bert架构的入门学习&#xff1a; 介绍Transformer架构&#xff0c;理解编码器和解码器的工作原理&#xff1b;掌握Bert模型架构…

Kafka生产与消费示例

Kafka生产与消费流程 Kafka是一款消息中间件&#xff0c;消息中间件本质就是收消息与发消息&#xff0c;所以这节课我们会从一条消息开始生产出发&#xff0c;去了解生产端的运行流程&#xff0c;然后简单的了解一下broker的存储流程&#xff0c;最后这条消息是如何被消费者消…

SpringMvc--CRUD

目录 一.什么是SpringMvc--CRUD 二.前期准备 公共页面跳转(专门用来处理页面跳转) 三.ssm之CRUD后端实现 配置pom.xml 双击mybatis-generator:generate自动生成mapper 编写generatorConfig.xml 项目结构 编写PagerAspect切面类 编写hpjyBiz接口类 编写hpjyBizImpl接…