内容简介:版权声明:本文为博主尹成联系QQ77025077,微信18510341407原创文章,欢迎转载侵权不究。 https://blog.csdn.net/yincheng01/article/details/84135842
版权声明:本文为博主尹成联系QQ77025077,微信18510341407原创文章,欢迎转载侵权不究。 https://blog.csdn.net/yincheng01/article/details/84135842
服务端实现
import ( "fmt" "net" "os" "strings" ) //存储客户端连接, key,ip端口,value 链接对象 var onlineConnsMap = make(map[string]net.Conn) //消息队列,缓冲区 var messageQueue = make(chan string, 1000) //消息,处理程序退出 var quitchan = make(chan bool) func CheckErrorS(err error) { if err != nil { fmt.Println("网络错误", err.Error()) os.Exit(1) } } func Processinfo(conn net.Conn) { buf := make([]byte, 1024) //开创缓冲区 defer func() { //关闭连接 conn.Close() fmt.Println("连接已关闭:",conn.RemoteAddr()) }() for { n, err := conn.Read(buf) //读取数据 if err != nil { fmt.Println("读取客户端消息出错,err=",err) break } if n != 0 { //消息处理, message := string(buf[0:n]) fmt.Printf("受到客户端%v消息:%s\n",conn.RemoteAddr(),message) //消息队列存储消息 messageQueue <- message fmt.Println("该条消息已加入队列...") }else{ fmt.Println("读取客户端消息长度为0") } } } //消息的协程 func consumeMessage() { for { select { case message := <-messageQueue: //取出消息 fmt.Println("已从队列中取出消息") strs := strings.Split(message, "#") //字符串切割 if len(strs) > 1 { //127.0.0.1:12345#去死 //截取地址并裁减头尾空白 addr := strs[0] addr = strings.TrimSpace(addr) //截取内容 msg := strs[1] //给所有客户端群发此消息 /*for addr, conn := range onlineConnsMap { //循环在线列表 _, err := conn.Write([]byte(msg)) fmt.Println("服务器发送消息", msg, "给", addr) if err != nil { fmt.Println("在线链接发送失败") } }*/ //@某人,发消息 if conn, ok := onlineConnsMap[addr]; ok { _, err := conn.Write([]byte(msg)) fmt.Println("服务器发送消息", msg) if err != nil { fmt.Println("在线链接发送失败") } } } case <-quitchan: //处理退出 os.Exit(0) } } } func main() { //建立TCP服务器 listener, err := net.Listen("tcp", "127.0.0.1:8898") CheckErrorS(err) defer listener.Close() //关闭网络 fmt.Println("服务器正在等待") go consumeMessage() for { conn, err := listener.Accept() //新的客户端连接 CheckErrorS(err) //处理每一个客户端 addr := fmt.Sprint(conn.RemoteAddr()) //取出地址 onlineConnsMap[addr] = conn fmt.Println("客户端列表") fmt.Println("-------------------") for key := range onlineConnsMap { //循环每一个链接 fmt.Println(key) } go Processinfo(conn) } }
客户端呢实现
import ( "fmt" "net" "bufio" "os" ) func CheckErrorC(err error) { if err != nil { fmt.Println("网络错误", err.Error()) } } func MessageSend(conn net.Conn) { var input string for { reader := bufio.NewReader(os.Stdin) //读取键盘输入 data, _, _ := reader.ReadLine() //读取一行 input = string(data) //键盘输入转化为字符串 if input == "exit" { conn.Close() fmt.Println("客户端关闭") break } _, err := conn.Write([]byte(input)) //输入写入字符串 fmt.Println("发送消息", input) if err != nil { conn.Close() fmt.Println("客户端关闭") break } } } func main() { conn, err := net.Dial("tcp", "127.0.0.1:8898") //建立TCP服务器 defer conn.Close() //延迟关闭网络连接 CheckErrorC(err) //检查错误 go MessageSend(conn) //开启一个协程,处理发送 //conn.Write([]byte("hello nimei")) //协程,负责收取消息 buf := make([]byte, 1024) for { numOfBytes, err := conn.Read(buf) CheckErrorC(err) fmt.Println("收到服务器消息", string(buf[:numOfBytes])) } fmt.Println("客户端关闭") }
学院 Go 语言视频主页
https://edu.csdn.net/lecturer/1928以上所述就是小编给大家介绍的《网络通信4:TCP广播》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
The Linux Command Line
William E. Shotts Jr. / No Starch Press, Incorporated / 2012-1-17 / USD 39.95
You've experienced the shiny, point-and-click surface of your Linux computer-now dive below and explore its depths with the power of the command line. The Linux Command Line takes you from your very ......一起来看看 《The Linux Command Line》 这本书的介绍吧!