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)
    }
}
相关推荐
AI进化营-智能译站12 分钟前
ROS2 C++开发系列12-用多态与虚函数构建可扩展的ROS2机器人行为模块
开发语言·c++·ai·机器人
iCxhust16 分钟前
微机原理实践教程(C语言篇)---A002流水灯
c语言·开发语言·单片机·嵌入式硬件·51单片机·课程设计·微机原理
莎士比亚的文学花园37 分钟前
Linux驱动开发(3)——设备树
开发语言·javascript·ecmascript
图码1 小时前
如何用多种方法判断字符串是否为回文?
开发语言·数据结构·c++·算法·阿里云·线性回归·数字雕刻
U盘失踪了1 小时前
python curl转python脚本
开发语言·chrome·python
charlie1145141911 小时前
Linux 字符设备驱动:cdev、设备号与设备模型
linux·开发语言·驱动开发·c
handler011 小时前
Linux 内核剖析:进程优先级、上下文切换与 O(1) 调度算法
linux·运维·c语言·开发语言·c++·笔记·算法
FQNmxDG4S1 小时前
Java泛型编程:类型擦除与泛型方法的应用场景
java·开发语言·python
我星期八休息1 小时前
IT疑难杂症诊疗室:AI时代工程师Superpowers进化论
linux·开发语言·数据结构·人工智能·python·散列表
热心网友俣先生1 小时前
2026年第二十三届五一数学建模竞赛C题超详细解题思路+各问题可用模型推荐+部分模型结果展示
c语言·开发语言·数学建模