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> ...
随机推荐
- Java数据结构总述
array list map set 链表..array 和list类似,增删慢,读取快,list长度可变,array长度固定, 链表增删快的list set 是一个没有重复数据的集合 map 是一个 ...
- iOS热更新实现方式
heart.jpg 苹果静止热更新,可惜我的是企业app,没有这些约束了,随便用.(当然有些热更新已经可以通过苹果审核了,比如JSPatch)官网说的: JSPatch 平台 SDK 1.7.2 以上 ...
- 第三方应用如何在SAP Kyma上进行服务注册
Jerry之前的公众号文章 什么?在SAP中国研究院里还需要会PHP开发?提到了一个SAP Kyma的应用场景: 旅行兼社交达人伊森,使用经过SAP Kyma扩展之后的WordPress这个网站来写博 ...
- Oracle查看表之间的约束
----查看表约束 表格: user_constraints 查询外键约束条件 select ' select count(*) from '||TABLE_NAME||';'from user_co ...
- Java知识导航总图
1.系统构架 企业服务总线(ESB).微服务.面向服务的架构(SOA) 了解分布式文件存储系统,掌握集群化开发及部署 2.系统系统集成技术 Wsbservice.Socket 3.RPC远程调用的相关 ...
- Oracle 找到引起账户锁定的IP
在ORACLE数据库中,如果没有修改过FAILED_LOGIN_ATTEMPTS的话,默认10次尝试失败后就会锁住用户.此时再登录数据库,就会遇到ORA-28000: the account is l ...
- Scyther攻击输出图的解释(之二)
下面对 Needham-Schroeder 协议形式化分析 的攻击输出图 做一个解释: Needham-Schroeder使用ns3表示, ns3 协议形式化描述结果如下: /* * Needham ...
- 控制台警告libpng warning: iCCP: known incorrect sRGB profile
用控制台测试数据的时候,出现的这个问题.虽然只是一个警告但是看着就是不太舒服 ,见下图 弄了好长时间,无意间切换个输入法,原先使用的是QQ输入法 切换成微软五笔以后,竟然好了 好了 好了
- jade总结
随着时间的迁移,要跟官方api相匹配 jade的缺点 1.可移植性差 2.调试困难 3.性能不是非常出色(不是为性能设计,可以使用dot, http://olado.github.io/) 选择的 ...
- Python——DataFrame转list(包含两种)
import pandas as pd df = pd.DataFrame({'a':[1,3,5,7,4,5,6,4,7,8,9], 'b':[3,5,6,2,4,6,7,8,7,8,9]}) df ...