Go语言 之TCP聊天室
服务端流程图如下:

package main import (
"fmt"
"net"
) // 客户端结构体
type Client struct {
//用户通信
C chan string
//客户端名称
name string
//客户端地址
addr string
} //map存储在线用户
var is_online map[string]Client //消息通讯
var messages = make(chan string) //广播全局消息到客户端
func Message() {
is_online = make(map[string]Client) // 循环读取 message 通道中的数据
for {
// 通道 message 中有数据读到 msg 中。 没有,则阻塞
msg := <-messages // 一旦执行到这里,说明message中有数据了,解除阻塞。 遍历 map
for _, client := range is_online {
client.C <- msg // 把从Message通道中读到的数据,写到 client 的 C 通道中。
}
}
} //生产消息函数
func MakeMsg(client Client, msg string) (buf string) {
buf = "[" + client.addr + "]" + client.name + ": " + msg
return
} //发送消息给在线客户端
func WriteMsgToClient(conn net.Conn, client Client) {
for msg := range client.C {
conn.Write([]byte(msg))
}
} func Handler(conn net.Conn) { //把当前客户端添加到在线map中
addr := conn.RemoteAddr().String()
client := Client{make(chan string), addr, addr}
//将当前客户端加入在线字典列表中
is_online[addr] = client //创建一个协程,专门给当前客户端发消息
go WriteMsgToClient(conn, client) //将用户上线的消息放到全局消息中
messages <- MakeMsg(client, "login") // 创建一个新协程,循环读取用户发送的消息,广播给在线用户
go func() {
for {
buf := make([]byte, 2048)
//读取客户端数据
n, _ := conn.Read(buf)
if n == 0 {
fmt.Printf("用户%s退出登录\n", client.name)
//将当前用户从在线字典中删除
delete(is_online, addr)
//通知其他客户端该用户退出登录
messages <- MakeMsg(client, "logout")
return
}
msg := string(buf[:n])
//将客户端发的消息加入到全局消息通道中
messages <- MakeMsg(client, msg)
}
}()
//让协程不停止运行
for { }
} func main() {
//奖励tcp监听
listen, err := net.Listen("tcp", ":8000")
if err != nil {
fmt.Println(err.Error())
return
}
defer listen.Close() //创建协程处理消息
go Message() for {
//阻塞等待客户端连接
conn, err := listen.Accept()
if err != nil {
fmt.Println(err.Error())
}
//创建协程处理客户端事件
go Handler(conn)
defer conn.Close()
}
}
效果图如下:


Go语言 之TCP聊天室的更多相关文章
- 与众不同 windows phone (30) - Communication(通信)之基于 Socket TCP 开发一个多人聊天室
原文:与众不同 windows phone (30) - Communication(通信)之基于 Socket TCP 开发一个多人聊天室 [索引页][源码下载] 与众不同 windows phon ...
- 基于tcp和多线程的多人聊天室-C语言
之前在学习关于网络tcp和多线程的编程,学了知识以后不用一下总绝对心虚,于是就编写了一个基于tcp和多线程的多人聊天室. 具体的实现过程: 服务器端:绑定socket对象->设置监听数-> ...
- 基于TCP/IP的局域网聊天室---C语言
具备注册账号,群聊,查看在线人员信息,私发文件和接收文件功能,因为每个客户端只有一个属于自己的socket,所以无论客户端是发聊天消息还是文件都是通过这一个socket发送, 这也意味着服务器收发任何 ...
- Go语言实践_实现一(服务器端)对多(客户端)在线聊天室
一.目的 运用Go语言中的goroutine和通道实现一个简单的一个服务器端对多个客户端的在线聊天 软件环境:Goland,Go1.9 代码仓库链接 二.设计思路 与一对一的设计思路类似,就是加了个线 ...
- Go语言实践_实现一(客户端)对一(服务器端)聊天室
一.目的 使用Go语言实现一个服务器端与客户端的聊天室. 软件:Goland,Go1.9 代码仓库地址 二.思路 1,首先启动服务器端,使用listen_socket函数监听IP地址上的客户端连接: ...
- C语言实现聊天室(windows版本)
来源:微信公众号「编程学习基地」 目录 C语言聊天室 运行效果 分析设计 多线程 线程的同步 服务端设计 遇到的问题 C语言聊天室 基于 tcp 实现群聊功能,本项目设计是在windows环境下基于套 ...
- JAVA基础知识之网络编程——-基于TCP通信的简单聊天室
下面将基于TCP协议用JAVA写一个非常简单的聊天室程序, 聊天室具有以下功能, 在服务器端,可以接受客户端注册(用户名),可以显示注册成功的账户 在客户端,可以注册一个账号,并用这个账号发送信息 发 ...
- 奇妙的go语言(聊天室的开发)
[ 声明:版权全部,欢迎转载,请勿用于商业用途. 联系信箱:feixiaoxing @163.com] 这是一篇关于聊天室开发的博客,原来文章的地址来自于此.这篇文章非常具有代表性,对于代码中的函数 ...
- 网络编程TCP协议-聊天室
网络编程TCP协议-聊天室(客户端与服务端的交互); <span style="font-size:18px;">1.客户端发数据到服务端.</span> ...
随机推荐
- 使用swagger在netcorewebapi项目中自动生成文档
一.背景 随着前后端分离模式大行其道,我们需要将后端接口撰写成文档提供给前端,前端可以查看我们的接口,并测试,提高我们的开发效率,减少无效的沟通.在此情况下,通过代码自动生成文档,这种需求应运而生,s ...
- 13.MyBatis注解式开发
mybatis 的注解,主要是用于替换映射文件.而映射文件中无非存放着增.删.改.查 的 SQL 映射标签.所以,mybatis 注解,就是要替换映射文件中的 SQL 标签. mybatis 官方文档 ...
- 【2018-01-26】SqlServer 检查死锁和阻塞
利用sys.sysprocesses SQL进程检查是否出现死锁和阻塞 Sys.SysProcesses 系统表是一个很重要的系统视图,主要用来定位与解决Sql Server的阻塞和死锁 select ...
- Hosts 长期更新【已停】
修改hosts篇 [2018.1.3] 由于google的对应的hosts更新过于频繁,再加上上次(18+1)大之后,国家政策原因,网上hosts更新基本上都停了,github的项目也陆续挂掉了. 还 ...
- WdatePicker日期控件使用与值获取,以及选择日期完毕触发事件
踩过无数坑,调试了很长时间,写出适合自己需求的方法需求:没有查询按钮,要求选择日期后自动触发查询事件(只有日期选择完成后才触发), 解决方案:代码如下:检索开始时间: <input type=& ...
- IIS设置网站为HTTPS并且将HTTP重定向到HTTPS
第一步:下载证书,导入证书到IIS https://help.aliyun.com/knowledge_detail/95502.html 站点绑定https 第二部:安装URL重写模块 rewrit ...
- vue2 v-for
- c++对c的扩展----引用类型
变量是一个内存的别名,程序通过变量名使用内存空间,当然一个内存空间可以起多个别名么? 答案:可以,这就是c++中引用的由来,引用就是给变量起别名 引用是c++的概念!!!况且声明引用的符号&十 ...
- 函数对话框confirm()
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- list,tuple,set,dict基础
list # @Auther : chen # @Time : 2018/4/26 19:55 # @File : list_ex.py # @SoftWare : PyCharm # list1 = ...