go语言实现聊天服务器,可自增自减的协程池
2018-03-17 21:55
489 查看
刚来公司实习,每天都在划水,划水狗一只。自己写点东西,大家有意见可以直接留言。
功能:基于go语言和协程池,实现一个简单的聊天服务器。
服务器代码:
/*/////////////////////////////
import (
功能:基于go语言和协程池,实现一个简单的聊天服务器。
服务器代码:
/*/////////////////////////////
date:2018-3-17
writer:fengzi
function:用go语言,基于一个可自增的协程池,实现多人聊天
功能。函数首先创建协程池,然后根据用户连接,创建
多余的协程加入协程池,如果长时间未使用多余的协程,
系统自动回收多余协程。
/////////////////////////////*/
import (
"fmt"
// "io"
"net"
)
var player map[net.Conn]int = map[net.Conn]int{} //存储用户连接
var message = make(chan net.Conn, 20) //用户连接的信道
var num int = 0 4000 //连接的用户数量
var channelnum int = 0 //开辟的协程数量
var boolexit int = 0 //是否需要关闭多余协程
func main() {
socket, err := net.Listen("tcp", "localhost:8080")
if err != nil {
fmt.Println("net listen error:", err)
return
}
defer socket.Close()
for i := 0; i < 2; i++ {
channelnum++
go talkChannel()
}
for {
conn, err := socket.Accept()
if err != nil {
continue
}
message <- conn
//扩充协程池
if num >= 2 {
fmt.Println("get new channel", num)
channelnum++
go talkChannel()
}
//如果用户数量长时间小于现在的协程数量,那么关闭多余协程
if (channelnum >= 2) && (num < channelnum) {
boolexit++
} else {
boolexit = 0
}
fmt.Println("boolexit num:", boolexit)
//连续十次未用到多余协程,关闭多余协程
if boolexit > 10 {
message <- nil
boolexit = 0
}
//go talk(conn)
}
}
func talkChannel() {
for {
conn := <-message
//如果传递的是空,则关闭该协程
if conn == nil {
fmt.Println("close channel")
break
}
fmt.Println("channel get one")
num++
fmt.Println("talkchannel used:", num)
defer conn.Close()
player[conn] = 0
for {
buf := make([]byte, 128)
n, err := conn.Read(buf)
if err != nil {
delete(player, conn)
fmt.Println("one client close:", conn)
break
}
buf = buf[0:n]
sendall(conn, buf)
}
num--
}
}
func talk(conn net.Conn) {
defer conn.Close()
player[conn] = 0
for {
buf := make([]byte, 8192)
n, err := conn.Read(buf)
if err != nil {
delete(player, conn)
fmt.Println("one client close:", conn)
break
}
buf = buf[0:n]
fmt.Println(buf)
sendall(conn, buf)
}
}
//广播发送
func sendall(conn net.Conn, buf []byte) {
for tmp, _ := range player {
if tmp != conn {
tmp.Write(buf)
}
}
}客户端:
import (
"bufio"
"fmt"
"net"
"os"
)
func main() {
socket, err := net.Dial("tcp", "localhost:8080")
if err != nil {
fmt.Println("net.dial error:", err)
return
}
defer socket.Close()
go get(socket)
for {
var buff string
tmp := bufio.NewReader(os.Stdin)
buff, _ = tmp.ReadString('\n')
buff = buff[0 : len(buff)-2]
//fmt.Println(buff)
socket.Write([]byte(buff))
}
}
func get(conn net.Conn) {
for {
buf := make([]byte, 1024)
n, err := conn.Read(buf)
if err != nil {
fmt.Println("socket link error:", err)
break
}
buf = buf[0:n]
fmt.Println("others send:", string(buf))
}
}
相关文章推荐
- go语言实现聊天服务器的示例代码
- Go语言服务器开发之简易TCP客户端与服务端实现方法
- Go语言异步服务器框架原理和实现
- 使用 Go 语言实现优雅的服务器重启
- Go语言实现简单的一个静态WEB服务器
- go 语言实现简单的WEB 服务器
- Go语言实现简单Web服务器的方法
- go 语言实现一个简单的 web 服务器
- Go语言实现的一个简单Web服务器
- Go语言实现简单的文件服务器
- Go语言(服务器开发):实现最简单的HTTP GET/POST接口
- Go语言中接口组合的实现方法
- 《Go语言入门》第一个Go语言Web程序——简单的Web服务器
- Go语言实现一致性哈希(Consistent Hashing)算法
- GO语言学习:go语言实现android应用的步骤
- Leaf - 一个由 Go 语言编写的开发效率和执行效率并重的开源游戏服务器框架
- 利用Tomcat7.0新特性,用BS实现CS的聊天服务器
- Windows下TCP聊天服务器与客户端雏形的实现
- 【Go】Go语言中反射包的实现原理(The Laws of Reflection)
- GO语言实现区块链Part5 Addresses