0 喜欢

Golang实现一个简单的聊天服务器

admin
admin
2022-08-27 23:56:47 阅读 1031

效果图

chat.jpg

服务器端

package main

import (
	"bufio"
	"fmt"
	"log"
	"net"
)

type Client struct {
	name string
	conn net.Conn
}

type Message struct {
	client Client
	msg    string
}

var (
	entering = make(chan Client)
	leaving  = make(chan Client)
	messages = make(chan Message)
)

func main() {
	listener, err := net.Listen("tcp", "localhost:3000")
	if err != nil {
		log.Fatal(err)
	}
	go broadcaster()
	for {
		conn, err := listener.Accept()
		if err != nil {
			log.Print(err)
			continue
		}
		go handleConn(conn)
	}
}

func broadcaster() {
	clients := make(map[Client]bool)

	for {
		select {
		case msg := <-messages:
			for cli := range clients {
				if msg.client != cli {
					fmt.Fprintln(cli.conn, msg.msg)
				}
			}
		case cli := <-entering:
			clients[cli] = true
		case cli := <-leaving:
			delete(clients, cli)
		}
	}
}

func handleConn(conn net.Conn) {
	who := conn.RemoteAddr().String()
	client := Client{name: who, conn: conn}
	message := Message{client: client}

	fmt.Fprintln(conn, "you are "+who)
	message.msg = who + " has arrived"
	messages <- message
	entering <- client

	input := bufio.NewScanner(conn)
	for input.Scan() {
		message.msg = who + ": " + input.Text()
		messages <- message
	}

	leaving <- client
	message.msg = who + " has left"
	messages <- message
	conn.Close()
}

客户端

package main

import (
	"bufio"
	"fmt"
	"log"
	"net"
	"os"
)

func main() {
	conn, err := net.Dial("tcp", "localhost:3000")
	if err != nil {
		log.Fatal(err)
	}
	go handleScan(conn)

	input := bufio.NewScanner(conn)
	for input.Scan() {
		log.Println(input.Text())
	}
}

func handleScan(conn net.Conn) {
	input := bufio.NewScanner(os.Stdin)
	for input.Scan() {
		fmt.Fprintln(conn, input.Text())
	}
}


关于作者
admin
admin
admin@ifront.net
 获得点赞 173
 文章阅读量 171274
文章标签