用GO写一个简单的聊天

49 阅读1分钟

服务端

package main

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

type Client struct {
    conn     net.Conn
    nickname string
    msg      string
}

var clients []Client

func main() {
    // 监听在8080端口
    listener, err := net.Listen("tcp", ":8080")
    if err != nil {
       log.Fatalf("无法启动服务器:", err)

    }
    defer listener.Close()

    log.Println("服务已经启动,等待客户端链接...")
    for {
       // 接受客户端链接
       conn, err := listener.Accept()
       if err != nil {
          log.Println("接受客户端链接失败", err)
       }
       // 创建一个新的客服端
       client := Client{conn: conn}

       // 将客户端添加到客户端列表
       clients = append(clients, client)

       go handleClient(client)
    }
}

func handleClient(client Client) {
    log.Printf("客户端 %s 已链接\n", client.conn.RemoteAddr())
    reader := bufio.NewReader(client.conn)
    for {
       // 读取客户端发送的消息
       message, err := reader.ReadString('\n')
       if err != nil {
          log.Printf("读取客户端消息失败: %s\n", client.conn.RemoteAddr())
          break
       }

       // 处理消息
       message = strings.TrimSpace(message)
       if client.nickname == "" {
          client.nickname = message
          log.Printf("客户端 %s 设置昵称为 %s\n", client.conn.RemoteAddr(), client.nickname)
       } else {
          log.Printf("收到来自 %s 的消息: %s\n", client.conn.RemoteAddr(), message)
          //broadcastMessage(client.nickname, message)
          go readInputAndSendToClient(client)
       }
    }
}

func sendMessageToClient(client Client, message string) {
    _, err := client.conn.Write([]byte(message))
    if err != nil {
       log.Printf("向客户端 %s 发送消息失败:%s\n", client.conn.RemoteAddr(), err)
    }
}

func readInputAndSendToClient(client Client) {
    reader := bufio.NewReader(os.Stdin)
    for {
       fmt.Print("请输入消息:")
       message, _ := reader.ReadString('\n')
       sendMessageToClient(client, message)
    }
}

客户端

package main

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

func main() {
    // 连接到聊天服务器
    conn, err := net.Dial("tcp", "localhost:8080")
    if err != nil {
       log.Fatal("无法链接到服务器:", err)
    }
    defer conn.Close()

    // 启动一个goroutine用于接收服务器消息
    go receiveMessage(conn)

    // 从标准输入读取用户输入,并发送到服务器
    scanner := bufio.NewScanner(os.Stdin)
    for scanner.Scan() {
       message := scanner.Text()
       _, err := conn.Write([]byte(message + "\n"))
       if err != nil {
          log.Println("发送消息失败", err)
          break
       }
    }
    if scanner.Err() != nil {
       log.Println("读取用户输入失败:", scanner.Err())
    }
}

func receiveMessage(conn net.Conn) {
    reader := bufio.NewReader(conn)
    for {
       message, err := reader.ReadString('\n')
       if err != nil {
          log.Println("接收消息失败:", err)
          break
       }
       message = strings.TrimSpace(message)
       log.Println("收到消息:", message)
    }
}