在一个服务器上监听两个端口

huangapple go评论90阅读模式
英文:

Listen to 2 Ports on 1 Server

问题

我正在尝试修改我的回声服务器程序,以创建一个聊天客户端。目前,当我启动客户端时,我的服务器会监听一个端口。然后,客户端可以输入并发送消息到服务器,服务器会将其回显。

然而,我希望能够连接两个客户端到两个不同的端口,并让客户端通过服务器互相发送消息。有没有办法可以实现这个?我假设第一步是监听两个端口而不是一个。

以下是我目前的代码。

服务器:

package main

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

func main() {
    fmt.Println("The server is listening on Port 3000")
    listener, _ := net.Listen("tcp", "localhost:3000")
    //listener2, _ := net.Listen("tcp", "localhost:8080")

    defer listener.Close()
    //defer listener2.Close()

    // Listen for connections
    for {
        conn, _ := listener.Accept()
        //conn2, _ := listener2.Accept()
        fmt.Println("New connection found!")

        go listenConnection(conn)
        //go listenConnection(conn2)
    }
}

//Listen for messages and reply
func listenConnection(conn net.Conn) {
    fmt.Println("Yay")
    for {
        buffer := make([]byte, 1400)
        dataSize, err := conn.Read(buffer)
        if err != nil {
            fmt.Println("Connection has closed")
            return
        }

        //This is the message you received
        data := buffer[:dataSize]
        fmt.Print("Received message: ", string(data))

        // Send the message back
        _, err = conn.Write(data)
        if err != nil {
            log.Fatalln(err)
        }
        fmt.Print("Message sent: ", string(data))
    }
}

客户端:

package main

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

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

    for {
        reader := bufio.NewReader(os.Stdin)
        fmt.Print("Enter text: ")
        text, _ := reader.ReadString('\n')

        _, err = conn.Write([]byte(text))
        if err != nil {
            log.Fatalln(err)
        }

        for {
            buffer := make([]byte, 1400)
            dataSize, err := conn.Read(buffer)
            if err != nil {
                fmt.Println("The connection has closed!")
                return
            }

            data := buffer[:dataSize]
            fmt.Println("Received message: ", string(data))
            break
        }

    }
}

有没有办法在一个服务器上监听两个客户端(端口),并让它们进行通信?是否可以让两个客户端使用同一个端口?我尝试在服务器程序中添加另一个监听器,但是我暂时将这些行注释掉了,因为它们没有起作用。我将非常感谢任何帮助!

英文:

I am trying to modify my echo server program in order to create a chat client. Currently, I have my server listening to a port when I start up my client. Then, the client can type and send a message to the server and the server will echo it back.

However, I would like to be able to connect 2 clients to 2 different ports and let the clients send messages to each other over the server. Is there any way I could do this? I am assuming that the first step would be to listen to 2 ports instead of one.

Here is what I have so far.

Server:

package main
 
import (
        "fmt"
        "log"
        "net"
)
 
func main() {
        fmt.Println("The server is listening on Port 3000")
        listener, _ := net.Listen("tcp", "localhost:3000")
		//listener2, _ := net.Listen("tcp", "localhost:8080")

        defer listener.Close()
		//defer listener2.Close()
       
        // Listen for connections
        for {
                conn, _ := listener.Accept()
				//conn2, _ := listener2.Accept()
                fmt.Println("New connection found!")
               
                go listenConnection(conn)
				//go listenConnection(conn2)
        }
}
 
//Listen for messages and reply
func listenConnection(conn net.Conn) {
		fmt.Println("Yay")
        for {
                buffer := make([]byte, 1400)
                dataSize, err := conn.Read(buffer)
                if err != nil {
                    fmt.Println("Connection has closed")
                    return
                }
               
                //This is the message you received
                data := buffer[:dataSize]
                fmt.Print("Received message: ", string(data))
               
                // Send the message back
                _, err = conn.Write(data)
                if err != nil {
                        log.Fatalln(err)
                }
                fmt.Print("Message sent: ", string(data))
        }
}

Client:

package main
 
import (
        "fmt"
        "log"
        "net"
		"bufio"
		"os"
)
 
func main() {
        conn, err := net.Dial("tcp", "localhost:3000")
        if err != nil {
                log.Fatalln(err)
        }

for {
 		reader := bufio.NewReader(os.Stdin)
		fmt.Print("Enter text: ")
		text, _ := reader.ReadString('\n')

        _, err = conn.Write([]byte(text))
        if err != nil {
                log.Fatalln(err)
        }
 
        for {
                buffer := make([]byte, 1400)
                dataSize, err := conn.Read(buffer)
                if err != nil {
                        fmt.Println("The connection has closed!")
                        return
                }
 
                data := buffer[:dataSize]
                fmt.Println("Received message: ", string(data))
				break
        }

	}
}

Is there any way to listen to 2 clients (ports) on 1 server and let them communicate? Is it possible to do this with both clients on the same port? I tried adding another listener in the Server program, but I commented those lines out for now as they did not work. I will appreciate any help!

答案1

得分: 9

问题中的服务器代码在同一个端口上处理多个客户端。

要使用两个端口,创建两个监听器,并在单独的goroutine中运行这些监听器的接受循环:

func main() {
    fmt.Println("服务器正在监听端口3000")
    listener, err := net.Listen("tcp", "localhost:3000")
    if err != nil {
        log.Fatal(err)
    }
    listener2, err := net.Listen("tcp", "localhost:8080")
    if err != nil {
        log.Fatal(err)
    }
    go acceptLoop(listener)
    acceptLoop(listener2)  // 在主goroutine中运行
}

func acceptLoop(l net.Listener) {
    defer l.Close()
    for {
        c, err := l.Accept()
        if err != nil {
            log.Fatal(err)
        }
        fmt.Println("发现新连接!")
        go listenConnection(c)
    }
}

此外,不要忽略错误。此答案中的代码通过调用log.Fatal处理错误。这可能适用于您的应用程序,也可能不适用。

英文:

The server code in the question handles multiple clients on the same port.

To work with two ports, create two listeners and run the accept loops for these listeners in separate goroutines:

func main() {
    fmt.Println("The server is listening on Port 3000")
    listener, err := net.Listen("tcp", "localhost:3000")
    if err != nil {
        log.Fatal(err) 
    }
    listener2, err := net.Listen("tcp", "localhost:8080")
    if err != nil {
        log.Fatal(err)
    }
    go acceptLoop(listener)
    acceptLoop(listener2)  // run in the main goroutine
}

func acceptLoop(l net.Listener) {
    defer l.Close()
    for {
            c, err := l.Accept()
            if err != nil {
                log.Fatal(err)
            }
            fmt.Println("New connection found!")
            go listenConnection(c)
    }
}

Also, don't ignore errors. The code in this answer handles errors by calling log.Fatal. That may or may not be appropriate for your application.

huangapple
  • 本文由 发表于 2016年3月29日 05:03:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/36271156.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定