Ubuntu下Go语言TCP广播服务器实现

最近在学习Go语言网络编程,突然想到很久以前的用C语言写过的TCP广播聊天程序,然后就用Go尝试写了一遍,在此做个记录。

目录

1.广播结构

2.实现效果

3.源码

4.Go语言学习参考网站


1.广播结构

2.实现效果

服务器:

 客户端1:

 客户端2:

 客户端3:

3.源码

server.go

package mainimport ("encoding/json""fmt""net""strings"
)// client info
type Client struct {Chan chan []byteAddr string
}// 广播信息
type Msg struct {Content stringUser    string
}// 客户端信息存储,IP和端口字符串为key
var onlineClients = make(map[string]Client)// 广播消息的通道
var broadcastCh = make(chan Msg)// 遍历通知客户端
func broadcastMessageManager() {for {//广播通道取数据msg := <-broadcastCh//遍历客户端发送数据for _, client := range onlineClients {msgBytes, _ := json.Marshal(msg)client.Chan <- msgBytes}}
}// 接收客户端消息,并将消息放入广播消息通道
func readClient(conn net.Conn) {for true {data := make([]byte, 1024)n, _ := conn.Read(data)content := strings.TrimSpace(string(data[:n]))if len(content) <= 0 {continue}broadcastCh <- Msg{Content: content, User: conn.RemoteAddr().String()}fmt.Printf("%s say: %s\n", conn.RemoteAddr().String(), content)}
}// 通知客户端消息
func notifyMsgToClient(conn net.Conn, client Client) {for {msgBytes := <-client.Chan_, _ = conn.Write(msgBytes)}
}func handleConnect(conn net.Conn) {addr := conn.RemoteAddr().String()fmt.Println("connect cilent: ", conn.RemoteAddr().String())client := Client{make(chan []byte), addr}onlineClients[addr] = clientcontent := client.Addr + " coming!"broadcastCh <- Msg{Content: content, User: "system info"}go readClient(conn)go notifyMsgToClient(conn, client)
}func main() {fmt.Println("server starting ...")listener, err := net.Listen("tcp", "127.0.0.1:8181")if err != nil {fmt.Println("net.Listen err: ", err)return}//遍历通知客户端go broadcastMessageManager()for {conn, err := listener.Accept()if err != nil {fmt.Println("listener.Accept err: ", err)continue}//goroutine处理用户连接go handleConnect(conn)}}

client.go

package mainimport ("bufio""encoding/json""fmt""net""os"
)// 广播信息
type Msg struct {Content stringUser    string
}func readMsg(conn net.Conn) {for {res := make([]byte, 1024)n, err := conn.Read(res)if err != nil {fmt.Println(err)return}result := res[:n]var msg Msgjson.Unmarshal(result, &msg)fmt.Printf("%s: %s\n", msg.User, msg.Content)}
}func writeMsg(conn net.Conn) {for true {// 从标准输入生成读对象reader := bufio.NewReader(os.Stdin)// 读到换行content, _ := reader.ReadBytes('\n')if len(content) <= 0 {continue}// 发送数据conn.Write(content)}
}func main() {conn, err := net.Dial("tcp", "127.0.0.1:8181")if err != nil {fmt.Println(err)return}defer conn.Close()// 起goroutine接收服务器广播的消息go readMsg(conn)// 命令行接收输入并发送给服务器writeMsg(conn)}

4.Go语言学习参考网站

Go言入门教程:
http://c.biancheng.net/golang/

Go编程参考:
http://www.yuan316.com/post/Go%E8%AF%AD%E8%A8%80/

Go语言标准库:
https://pkg.go.dev/std

Go虎贲
https://www.zhihu.com/column/c_1438631789279076353

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

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

相关文章

计算机毕业论文内容参考|基于Python的入侵检测系统的设计与实现

文章目录 导文摘要前言绪论课题背景国内外现状与趋势课题内容相关技术与方法介绍系统分析系统设计系统实现系统测试总结与展望导文 计算机毕业论文内容参考|基于Python的入侵检测系统的设计与实现 摘要 本文介绍了基于Python的入侵检测系统的设计与实现。首先,简要概述了入侵…

语言模型BERT理解

一、BERT概述 BERT是由Google在2018年提出的一种预训练语言模型。BERT的创新之处在于采用了双向Transformer编码器来生成上下文相关的词向量表示。 传统的单向语言模型只考虑了左侧或右侧的上下文信息&#xff0c;而BERT则同时考虑了左侧和右侧的上下文信息&#xff0c;使得生…

uni-app获取系统信息(手机牌子、手机型号、屏幕宽度、屏幕高度)

uni.getSystemInfo({success(res) {console.log(res.brand) //手机牌子console.log(res.model) //手机型号console.log(res.screenWidth) //屏幕宽度console.log(res.screenHeight) //屏幕高度}) .exec()}}); 如下 官网链接&#xff1a;系统信息的概念 | uni-app官网

【ES6】中构造函数的语法糖 —— Class(类)

在现代前端开发中&#xff0c;JavaScript的面向对象编程成为了主流。ES6引入了class关键字&#xff0c;使得开发者可以更方便地使用面向对象的方式编写代码&#xff0c;更接近传统语言的写法。ES6的class可以看作是一个语法糖&#xff0c;它的绝大部分功能ES5都可以做到&#x…

Leetcode每日一题:167. 两数之和 II - 输入有序数组(2023.7.8 C++)

目录 167. 两数之和 II - 输入有序数组 题目描述&#xff1a; 实现代码与解析&#xff1a; 暴力&#xff08;超时&#xff09; 双指针 原理思路&#xff1a; 二分 原理思路&#xff1a; 167. 两数之和 II - 输入有序数组 题目描述&#xff1a; 给你一个下标从 1 开始的…

【机器学习核心总结】什么是随机森林

什么是随机森林 森林里有很多树&#xff0c;随机森林里有很多决策树。 随机森林是决策树的升级版&#xff0c;随机指的是树的生长过程。世上没有两片相同的树叶&#xff0c;随机森林中的树也各不相同。在构建决策树时&#xff0c;我们会从训练数据中有放回的随机选取一部分样本…

【C语言】指针进化 !!!

前言 &#x1f388;大家好&#xff0c;我是何小侠&#x1f388; &#x1f343;大家可以叫我小何或者小侠&#x1f343; &#x1f490;希望能通过写博客加深自己对于学习内容的理解&#x1f490; &#x1f338;也能帮助更多人理解和学习&#x1f338; 兰生幽谷&#xff0c;不为…

交叉熵、Focal Loss以及其Pytorch实现

交叉熵、Focal Loss以及其Pytorch实现 本文参考链接&#xff1a;https://towardsdatascience.com/focal-loss-a-better-alternative-for-cross-entropy-1d073d92d075 文章目录 交叉熵、Focal Loss以及其Pytorch实现一、交叉熵二、Focal loss三、Pytorch1.[交叉熵](https://pyto…

SpringCloud入门实战(十二)-Sleuth+Zipkin分布式请求链路跟踪详解

&#x1f4dd; 学技术、更要掌握学习的方法&#xff0c;一起学习&#xff0c;让进步发生 &#x1f469;&#x1f3fb; 作者&#xff1a;一只IT攻城狮 &#xff0c;关注我&#xff0c;不迷路 。 &#x1f490;学习建议&#xff1a;1、养成习惯&#xff0c;学习java的任何一个技术…

Keras-5-深度学习用于文本和序列-处理文本数据

深度学习用于文本和序列 说明: 本篇学习记录为&#xff1a;《Python 深度学习》第6章第1节&#xff08;处理文本数据&#xff09; 知识点: 深度学习处理文本或序列数据的基本方法是&#xff1a;循环神经网络 (recurrent neural network) 和 一维卷积神经网络 (1D convert)&…

SpringBoot—统一功能处理

SpringBoot—统一功能处理 &#x1f50e;小插曲(通过一级路由调用多种方法)&#x1f50e;使用拦截器实现用户登录权限的统一校验自定义拦截器将自定义拦截器添加至配置文件中拦截器的实现原理统⼀访问前缀添加 &#x1f50e;统一异常的处理&#x1f50e;统一数据格式的返回统一…

天天刷题-->LeetCode(两数相加)

个人名片&#xff1a; &#x1f405;作者简介&#xff1a;一名大二在校生&#xff0c;热爱生活&#xff0c;爱好敲码&#xff01; \ &#x1f485;个人主页 &#x1f947;&#xff1a;holy-wangle ➡系列内容&#xff1a; &#x1f5bc;️ tkinter前端窗口界面创建与优化 &…