1、IM:基础连接

IM:基础连接

1、服务端

go 复制代码
// server.go
package main

import (
    "bufio"
    "fmt"
    "net"
    "strings"
    "sync"
)

var (
    clients = make(map[net.Conn]string)
    mu      sync.Mutex
)

func broadcast(msg string, sender net.Conn) {
    mu.Lock()
    defer mu.Unlock()

    for conn := range clients {
        if conn != sender {
            fmt.Fprintln(conn, msg)
        }
    }
}

func handleClient(conn net.Conn) {
    defer conn.Close()

    // 读取用户名(第一行)
    reader := bufio.NewReader(conn)
    username, err := reader.ReadString('\n')
    if err != nil {
        fmt.Println("Error reading username:", err)
        return
    }
    username = strings.TrimSpace(username)
    if username == "" {
        username = "Anonymous"
    }

    mu.Lock()
    clients[conn] = username
    mu.Unlock()

    fmt.Printf("User %s joined.\n", username)
    broadcast(fmt.Sprintf("[Server] %s joined the chat.", username), conn)

    // 广播消息循环
    for {
        msg, err := reader.ReadString('\n')
        if err != nil {
            break
        }
        msg = strings.TrimSpace(msg)
        if msg == "" {
            continue
        }
        fullMsg := fmt.Sprintf("[%s] %s", username, msg)
        fmt.Println(fullMsg) // 服务端日志
        broadcast(fullMsg, conn)
    }

    // 用户断开
    mu.Lock()
    delete(clients, conn)
    mu.Unlock()
    broadcast(fmt.Sprintf("[Server] %s left the chat.", username), nil)
    fmt.Printf("User %s disconnected.\n", username)
}

func main() {
    listener, err := net.Listen("tcp", ":8080")
    if err != nil {
        panic(err)
    }
    defer listener.Close()

    fmt.Println("IM Server started on :8080")

    for {
        conn, err := listener.Accept()
        if err != nil {
            fmt.Println("Accept error:", err)
            continue
        }
        go handleClient(conn)
    }
}

2、客户端

go 复制代码
// client.go
package main

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

func main() {
    conn, err := net.Dial("tcp", "localhost:8080")
    if err != nil {
        panic(err)
    }
    defer conn.Close()

    fmt.Print("Enter your username: ")
    reader := bufio.NewReader(os.Stdin)
    username, _ := reader.ReadString('\n')
    username = strings.TrimSpace(username)

    // 发送用户名
    fmt.Fprintln(conn, username)

    // 启动 goroutine 接收消息
    go func() {
        in := bufio.NewScanner(conn)
        for in.Scan() {
            fmt.Println(in.Text())
        }
    }()

    // 主线程发送消息
    for {
        fmt.Print("> ")
        msg, _ := reader.ReadString('\n')
        msg = strings.TrimSpace(msg)
        if msg == "/quit" {
            break
        }
        fmt.Fprintln(conn, msg)
    }
}
相关推荐
风象南7 小时前
很多人说,AI 让技术平权了,小白也能乱杀老师傅 ?
人工智能·后端
雨中飘荡的记忆8 小时前
ElasticJob分布式调度从入门到实战
java·后端
Se7en2588 小时前
推理平台全景
后端
大漠_w3cpluscom8 小时前
你学不会 CSS,不是笨,是方向错了
后端
cipher12 小时前
ERC-4626 通胀攻击:DeFi 金库的"捐款陷阱"
前端·后端·安全
毅航12 小时前
自然语言处理发展史:从规则、统计到深度学习
人工智能·后端
JxWang0512 小时前
Task04:字符串
后端
树獭叔叔13 小时前
10-让模型更小更聪明,学而不忘:知识蒸馏与持续学习
后端·aigc·openai
JxWang0513 小时前
Task02:链表
后端