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
		}
	}
}

Goland 实现简单群聊【超时处理, 显示好友列表】_第1张图片

你可能感兴趣的:(Go,网络编程,网络,服务器)