go实现多聊天并发 服务端
package main import (
"fmt"
"net"
"time"
)
type Client struct {
ch chan string //用户发送数据的管道
name string //用户名
addr string//网络地址
}
var message = make(chan string) //用来保存用户的消息
//定义一个map 值为在线的用户
var onlineClientMap map[string]Client//
func main() {
listener,err := net.Listen("tcp","127.0.0.1:8000")
if err !=nil{
fmt.Println(err)
}
defer listener.Close()
go Manager()
//主协程,循环阻塞用户连接
for{
conn, err := listener.Accept()
if err!=nil{
fmt.Println(err)
continue
}
go handleConn(conn) } }
func makeMsg(client Client,msg string)(buff string){ buff ="["+client.addr+"]"+client.name+":"+msg+"\n"
return
} func handleConn(conn net.Conn){
cliAddr:= conn.RemoteAddr().String()
defer conn.Close()
client :=Client{
make(chan string),
cliAddr,
cliAddr,
}
onlineClientMap[cliAddr] = client
//给当前客户端发送信息
go writeMsgToClient(client,conn)
//广播某个在线
message<-"I am here\n"
message<- makeMsg(client,"login")
//是否主动退出
isQuit:=make(chan bool)
hasData:= make(chan bool)
//新开一个协程接收用户发过来的数据
go func() {
buff:= make([]byte,2048)
for{
n,err :=conn.Read(buff)
fmt.Println(n)
if err!=nil{
fmt.Println(nil)
}
if n==0{
fmt.Println("断开连接")
isQuit<-true
return
}
msg := string(buff[:n-1])
if len(msg)==3&& msg =="who"{
for _,tmp := range onlineClientMap{
msg = tmp.addr+":"+tmp.name+"\n"
conn.Write([]byte(msg)) }
}else{
message<-makeMsg(client,msg)
}
hasData<-true
}
}()
for{
select { case <-isQuit:
delete(onlineClientMap,cliAddr)//当前用户从map移除
message<-makeMsg(client,"login out")//广播退出
return
case <-hasData: case <-time.After(60*time.Second):
delete(onlineClientMap,cliAddr)//当前用户从map移除
message<-makeMsg(client,"time out")//广播退出
return
} } }
func Manager() {
onlineClientMap = make(map[string]Client)//给map分配空间
for{
msg := <-message
for _ ,client :=range onlineClientMap{
client.ch<-msg }
}
} func writeMsgToClient(client Client,conn net.Conn) {
for msg:= range client.ch{
conn.Write([]byte(msg))
} }
go实现多聊天并发 服务端的更多相关文章
- Socket聊天程序——服务端
写在前面: 昨天在博客记录自己抽空写的一个Socket聊天程序的初始设计,那是这个程序的整体设计,为了完整性,今天把服务端的设计细化记录一下,首页贴出Socket聊天程序的服务端大体设计图,如下图: ...
- linux网络编程学习笔记之三 -----多进程并发服务端
首先是fork()函数.移步APUE 8.3. 比較清晰的解释能够參考http://blog.csdn.net/lingdxuyan/article/details/4993883和http://w ...
- tcp并发服务端
TCP并发服务器:并发服务器的思想是每一个客户端的请求并不由服务器的主进程直接处理,而是服务器主进程创建一个子进程来处理. 创建TCP并发服务器的算法如下: socket(……): //创建一个TCP ...
- 利用sorket实现聊天功能-服务端实现
工具包 package loaderman.im.util; public class Constants { public static final String SERVER_IP = " ...
- linux c socket 并发 服务端
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types. ...
- TCP服务端实现并发
socket 在 tcp 协议下通信 客户端 import socket # 创建客户端TCP协议通信 c = socket.socket() # 与指定服务端握手 c.connect(('127 ...
- 基于TCP协议套接字,服务端实现接收客户端的连接并发
基于TCP协议套接字,服务端实现接收客户端的连接并发 服务端 import socket from multiprocessing import Process server=socket.socke ...
- 进程池与线程池、协程、协程实现TCP服务端并发、IO模型
进程池与线程池.协程.协程实现TCP服务端并发.IO模型 一.进程池与线程池 1.线程池 ''' 开进程开线程都需要消耗资源,只不过两者比较的情况下线程消耗的资源比较少 在计算机能够承受范围内最大限度 ...
- c++ 网络编程(九)LINUX/windows-IOCP模型 多线程超详细教程及多线程实现服务端
原文作者:aircraft 原文链接:https://www.cnblogs.com/DOMLX/p/9661012.html 先讲Linux下(windows下在后面可以直接跳到后面看): 一.线程 ...
随机推荐
- mysql 控制流函数
MySQL有4个函数是用来进行条件操作的,这些函数可以实现SQL的条件逻辑,允许开发者将一些应用程序业务逻辑转换到数据库后台. MySQL控制流函数: CASE WHEN[test1] THEN [r ...
- 大型web项目构建之负载均衡
日常开发和学习中经常会听到或者会看到“负载均衡”这个词汇,但是对于很多初级每天只面对增删改代码的开发人员来说,这个词汇好像离我们很遥远又很接近,很多人多多少少都有点一知半解 我结合以前在开发中遇到的场 ...
- Spring笔记3
动态代理** 特点:字节码随用随创建,随用随加载 作用:不修改源码的基础上对方法增强 分类: 基于接口的动态代理 基于子类的动态代理 基于接口的动态代理: 涉及的类:Proxy 如何创建代理对 ...
- jvm堆内存模型原理分析及堆内存分析工具jhat和MAT的使用超详细教程
- go语言学习笔记---读取文件io/ioutil 包
io/ioutil 包几个函数方法 名称 作用 备注 ReadAll 读取数据,返回读到的字节 slice 1 ReadDir 读取一个目录,返回目录入口数组 []os.FileInfo, 2 Re ...
- 2.5_Database Interface ODBC数据源及案例
分类 用户数据源 用户创建的数据源,称为“用户数据源”.此时只有创建者才能使用,并且只能在所定义的机器上运行.任何用户都不能使用其他用户创建的用户数据源. 系统数据源 所有用户在Windows下以服务 ...
- angularjs 动态加载指令------编译服务$compile
场景: 我们写了一个自定义的指令,这条指令需要一些数据,而这些数据需要在某些操作之后才能就绪,这时候,我们就需要在数据就绪之后,动态加载指令. 示例: js: $scope.$watch('repor ...
- iOS自动签名网站
node.js作为服务端,调用shell脚本进行iOS包重签名. 需要安装:nodejs ,forever 安装环境: 安装nodejs 安装forever: npm install forever ...
- netcore里使用jwt做登陆授权
1 什么是JWT? JWT是一种用于双方之间传递安全信息的简洁的.URL安全的表述性声明规范.JWT作为一个开放的标准(RFC 7519),定义了一种简洁的,自包含的方法用于通信双方之间以Json对象 ...
- redis键过期 (redis 2.6及以上)
EXPIRE key seconds 用来对一个键设置一个过期时间,第二个参数表示经过多少秒后键过期. 一个键过期后, 这个键将会被自动删除. 在Redis术语中,带有过期时间的键经常被称作volat ...