Goland 实现简单群聊【超时处理, 显示好友列表】

Server:

package main

import (
	"fmt"
	"net"
	"time"
)

type Client struct {
	C    chan string
	Name string
	Addr string
}

var Message = make(chan string)

var Online_Client map[string]Client

// 有消息了, 就转发出去
func Manager() {
	Online_Client = make(map[string]Client)
	for {
		msg := <-Message

		for _, iter := range Online_Client {
			iter.C <- msg
		}
	}
}

func WriteOther(Now_obj Client, Conn net.Conn) {
	for {
		for msg := range Now_obj.C {
			Conn.Write([]byte(msg))
		}
	}
}

func Handle(Conn net.Conn) {
	defer Conn.Close()

	obj := Client{Addr: Conn.RemoteAddr().String(), Name: Conn.RemoteAddr().String(), C: make(chan string)}
	Online_Client[obj.Addr] = obj
	fmt.Println(obj.Addr)
	go WriteOther(obj, Conn)

	quit := make(chan bool)
	hasdata := make(chan bool)

	go func() {
		buf := make([]byte, 1024)
		for {
			n, _ := Conn.Read(buf)
			fmt.Printf("Read len : %d, buf:%s\n", n, buf[:n])

			if n == 0 {
				quit <- true
				return
			} else if string(buf[:n-2]) == "who" { // who/r/n
				for _, iter := range Online_Client {
					//obj.C <- iter.Name
					Conn.Write([]byte(iter.Name + "\n"))
				}
			} else {
				Message <- string(obj.Name + ": " + string(buf[:n]))
			}
			hasdata <- true
		}
	}()

	Seng_msg := string(obj.Addr + "【" + obj.Name + "】 login\n")
	fmt.Println(Seng_msg)
	Message <- Seng_msg
	for {
		select {
		case <-quit:
			delete(Online_Client, Conn.RemoteAddr().String())
			Message <- string(obj.Addr + "【" + obj.Name + "】 Out\n")
			return

		case <-hasdata:

		case <-time.After(20 * time.Second):
			delete(Online_Client, Conn.RemoteAddr().String())
			Message <- string(obj.Addr + "【" + obj.Name + "】 Out\n")
			return
		}
	}

}
func main() {

	Listen, err := net.Listen("tcp", "127.0.0.1:8888")
	defer Listen.Close()
	if err != nil {
		fmt.Printf("Listen err: %s", err)
		return
	}

	go Manager() // 有消息了, 就转发出去
	for {
		Cli_conn, err1 := Listen.Accept()
		if err1 != nil {
			fmt.Printf("Accept err: %s", err1)
			return
		}

		go Handle(Cli_conn)
	}

}

Client:

package main

import (
	"fmt"
	"net"
	"os"
)

func main() {

	conn, ok := net.Dial("tcp", "127.0.0.1:8888")
	defer conn.Close()
	if ok != nil {
		fmt.Printf("%s\n", ok)
	}

	// 写
	go func() {
		buf := make([]byte, 1024)
		for {

			len, ok1 := os.Stdin.Read(buf)
			if ok1 != nil {
				fmt.Printf("%s\n", ok1)
				return
			}
			conn.Write(buf[:len])
		}
	}()

	islive := make(chan bool)
	// 读
	go func() {
		buf := make([]byte, 1024)
		for {
			n, ok2 := conn.Read(buf)
			if n == 0 {
				fmt.Printf("  close\n")
				islive <- true
				return
			}
			if ok2 != nil {
				fmt.Printf("  conn.Read(buf)conn.Read(buf)%s\n", ok2)
				return
			}
			fmt.Printf("%s", buf[:n])
		}
	}()

	for {
		select {
		case <-islive:
			return
		}
	}
}

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DongGu.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值