多端口连接的 UDP 服务器问题

时间:2021-05-06 23:23:42

标签: go networking udp

我有一个 UDP 服务器,它公开两个端口,8080 用于正常数据,8082 用于控制(保持活动信号)。当我启动服务器时,会创建一个新的 Server 实例。它有一个客户端列表:一个由 struct that 表示的客户端包含两种类型的 UDPConn,一种用于控制,一种用于数据。发生的情况是,当我运行 Client.go 时,我在两个端口都连接到服务器,但是服务器创建了两个客户端而不是一个客户端。向下是我的 Server.goClient.go 的一部分。如何为两个连接只创建一个用户?

Server.go

func main() {
    server := NewLobby()

    addressCntrl, err := net.ResolveUDPAddr(CONN_TYPE, CONN_CNTRL_PORT)
    if err != nil {
        log.Fatalf("Error resolving controller address: %s", err)
    }

    listenerCntrl, err := net.ListenUDP(CONN_TYPE, addressCntrl)
    defer listenerCntrl.Close()

    log.Printf("Listening controll on port %s", CONN_CNTRL_PORT)

    addressData, err := net.ResolveUDPAddr(CONN_TYPE, CONN_DATA_PORT)
    if err != nil {
        log.Fatalf("Error Resolving data address: %s", err)
    }

    listenerData, err := net.ListenUDP(CONN_TYPE, addressData)
    defer listenerData.Close()

    log.Printf("Listening data on port %s", CONN_DATA_PORT)

    for {
        buffer = make([]byte, 1024)
        listenerData.ReadFromUDP(buffer)
        c := NewClient(*listenerData, *listenerCntrl)
        server.Join(c)
    }
}

新服务器 (server.go)

func NewServer() *Server {
    server := &Server{
        clients:   make([]*Client, 0),
        chatRooms: make(map[string]*ChatRoom),
        incoming:  make(chan *Message),
        join:      make(chan *Client),
        leave:     make(chan *Client),
        delete:    make(chan *ChatRoom),
    }
    server.Listen()
    return server
}

NewClient (server.go)

func NewClient(connData net.UDPConn, connCntrl net.UDPConn) *Client {
    writerData := bufio.NewWriter(&connData)
    readerData := bufio.NewReader(&connData)

    writerCntrl := bufio.NewWriter(&connCntrl)
    readerCntrl := bufio.NewReader(&connCntrl)

    client := &Client{
        name:        CLIENT_NAME,
        chatRoom:    nil,
        incoming:    make(chan *Message),
        outgoing:    make(chan string),
        connData:    connData,
        connCntrl:   connCntrl,
        readerData:  readerData,
        writerData:  writerData,
        readerCntrl: readerCntrl,
        writerCntrl: writerCntrl,
    }

    log.Printf("New client connected")

    client.Listen()
    return client
}

Client.go

func main() {
    server := NewServer()

    addressCntrl, err := net.ResolveUDPAddr(CONN_TYPE, CONN_CNTRL_PORT)
    if err != nil {
        log.Fatalf("Error resolving controller address: %s", err)
    }

    listenerCntrl, err := net.ListenUDP(CONN_TYPE, addressCntrl)
    defer listenerCntrl.Close()

    log.Printf("Listening controll on port %s", CONN_CNTRL_PORT)

    addressData, err := net.ResolveUDPAddr(CONN_TYPE, CONN_DATA_PORT)
    if err != nil {
        log.Fatalf("Error Resolving data address: %s", err)
    }

    listenerData, err := net.ListenUDP(CONN_TYPE, addressData)
    defer listenerData.Close()

    log.Printf("Listening data on port %s", CONN_DATA_PORT)

    for {
        buffer = make([]byte, 1024)
        listenerData.ReadFromUDP(buffer)
        c := NewClient(*listenerData, *listenerCntrl)
        server.Join(c)
    }
}

输出示例如下

服务器输出

2021/05/06 20:03:52 Listening controll on port :8082
2021/05/06 20:03:52 Listening data on port :8080
2021/05/06 20:03:56 New client connected
2021/05/06 20:03:58 New client connected

客户端输出

Welcome to the server! Type "/help" to get a list of commands.
Welcome to the server! Type "/help" to get a list of commands.

如果需要,我的函数 Read()Write() 客户端如下。

阅读(client.go)

func Read(connData net.UDPConn, connCntrl net.UDPConn) {
    //Controller
    go func() {
        readerCntrl := bufio.NewReader(&connCntrl)
        for {
            str, _ := readerCntrl.ReadString('\n')
            if strings.Compare(str, "timeout") == 0 {
                os.Exit(1)
            }
        }
    }()

    //Data
    reader := bufio.NewReader(&connData)
    for {
        str, err := reader.ReadString('\n')
        if err != nil {
            fmt.Printf(MSG_DISCONNECT)
            wg.Done()
            return
        }
        fmt.Print(str)
    }
}

写入(client.go)

func Write(connData net.UDPConn, connCntrl net.UDPConn) {
    //Controller
    go func() {
        writerCntrl := bufio.NewWriter(&connCntrl)
        for range time.Tick(10 * time.Second) {
            writerCntrl.WriteString("ka")
        }
    }()

    //Data
    reader := bufio.NewReader(os.Stdin)
    writerData := bufio.NewWriter(&connData)
    for {
        input, err := reader.ReadString('\n')
        if err != nil {
            log.Fatalf("Error reading input: %s", err)
        }

        _, err = writerData.WriteString(input)
        if err != nil {
            log.Fatalf("Error writing input to server: %s", err)
        }

        err = writerData.Flush()
        if err != nil {
            log.Fatalf("Error flushing the input: %s", err)
            wg.Done()
        }
    }
}

0 个答案:

没有答案