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实现多聊天并发 服务端的更多相关文章

  1. Socket聊天程序——服务端

    写在前面: 昨天在博客记录自己抽空写的一个Socket聊天程序的初始设计,那是这个程序的整体设计,为了完整性,今天把服务端的设计细化记录一下,首页贴出Socket聊天程序的服务端大体设计图,如下图: ...

  2. linux网络编程学习笔记之三 -----多进程并发服务端

    首先是fork()函数.移步APUE 8.3.  比較清晰的解释能够參考http://blog.csdn.net/lingdxuyan/article/details/4993883和http://w ...

  3. tcp并发服务端

    TCP并发服务器:并发服务器的思想是每一个客户端的请求并不由服务器的主进程直接处理,而是服务器主进程创建一个子进程来处理. 创建TCP并发服务器的算法如下: socket(……): //创建一个TCP ...

  4. 利用sorket实现聊天功能-服务端实现

    工具包 package loaderman.im.util; public class Constants { public static final String SERVER_IP = " ...

  5. linux c socket 并发 服务端

    #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types. ...

  6. TCP服务端实现并发

    socket 在 tcp 协议下通信 客户端 import socket ​ # 创建客户端TCP协议通信 c = socket.socket() # 与指定服务端握手 c.connect(('127 ...

  7. 基于TCP协议套接字,服务端实现接收客户端的连接并发

    基于TCP协议套接字,服务端实现接收客户端的连接并发 服务端 import socket from multiprocessing import Process server=socket.socke ...

  8. 进程池与线程池、协程、协程实现TCP服务端并发、IO模型

    进程池与线程池.协程.协程实现TCP服务端并发.IO模型 一.进程池与线程池 1.线程池 ''' 开进程开线程都需要消耗资源,只不过两者比较的情况下线程消耗的资源比较少 在计算机能够承受范围内最大限度 ...

  9. c++ 网络编程(九)LINUX/windows-IOCP模型 多线程超详细教程及多线程实现服务端

    原文作者:aircraft 原文链接:https://www.cnblogs.com/DOMLX/p/9661012.html 先讲Linux下(windows下在后面可以直接跳到后面看): 一.线程 ...

随机推荐

  1. [转帖]Merkle树

    Merkle树 https://www.jianshu.com/p/fc439a8fd0de 所谓比特币交易就是从一个比特币钱包向另一个中转账,每笔交易都有数字签名来保证安全.一个交易一旦发生那么就是 ...

  2. 【RocketMQ源码学习】- 4. Client 事务消息源码解析

    介绍 > 基于4.5.2版本的源码 1. RocketMQ是从4.3.0版本开始支持事务消息的. 2. RocketMQ的消息队列能够保证生产端,执行数据和发送MQ消息事务一致性,而消费端的事务 ...

  3. C++ 读取 MATLAB 的 .m 文件,并发送到 MATLAB 运行

    本代码是由「Microsoft Visual Studio 2015 Enterprise」编写. 想要了解更多 C++ 与 MATLAB 混合编程的知识,可以参考我的另一篇博客:C++ 与 MATL ...

  4. Makefile 介绍

    makefile:是告诉编译器(交叉工具链)如何去编译.链接一个工程的规则.   一.概述 什 么是makefile?或许很多Winodws的程序员都不知道这个东西,因为那些Windows的IDE都为 ...

  5. Modelsim——显示状态机名称的方法

    方法在本人博客<状态机的Verilog写法>已经写明,为了方便查看,特意拎出来. 方法1: Testbench 设计文件含有状态机时,对应的仿真文件testbench里增加一段参数转ASC ...

  6. 使用 Issue 管理软件项目详解

    文章来源:http://www.ruanyifeng.com/blog/2017/08/issue.html 软件开发(尤其是商业软件)离不开项目管理,Issue 是最通用的管理工具之一. 本文介绍 ...

  7. R学习笔记3 数据处理

    1,日期类型 日期类型比较特殊,日期值通常以字符串的形式输入到R中,然后使用as.Date()函数转换为以数值形式存储的日期变量 mydate <- as.Date("2019-01- ...

  8. 【SQL Server数据迁移】32位的机器:SQL Server中查询ORACLE的数据

    从SQL Server中查询ORACLE中的数据,可以在SQL Server中创建到ORACLE的链接服务器来实现的,但是根据32位 .64位的机器和软件,需要用不同的驱动程序来实现. 在32位的机器 ...

  9. 3.建造模式(Builder)

    注:图片来源于 https://www.cnblogs.com/-saligia-/p/10216752.html 建造模式UML图解析: 代码: Director.h // // Created b ...

  10. 设置 SQL*Plus 的运行环境

    SQL*Plus 的运行环境是用来输入.执行 SQL*Plus 命令和显示返回结果的场所,设置合适的 SQL*Plus 运行环境,可以使 SQL*Plus 按照用户的要求运行和执行各种操作.set 命 ...