【问题标题】:How to create client server in Go language?如何用 Go 语言创建客户端服务器?
【发布时间】:2012-12-01 04:13:18
【问题描述】:

我是新来的, 我试图用 go 语言准备客户端服务器并尝试编写代码,但它没有提供任何输出。它没有给出任何错误,只是在听。

请有人帮助我,我想使用 go 创建身份验证系统,其中服务器使用用户名密码对客户端进行身份验证..

服务器:

package main

import (
        "fmt"
        "net"
)

func main() {
        service := "0.0.0.0:8080"
        tcpAddr, err := net.ResolveTCPAddr("tcp", service)
        checkError(err)
        listener, err := net.ListenTCP("tcp", tcpAddr)
        checkError(err)
        for {
                conn, err := listener.Accept()
                //fmt.Println("Server listerning")
                _, err = conn.Read([]byte("HEAD"))
                if err != nil {
                        conn.Close()
                }
                if err != nil {
                        continue
                }
        }
}

func checkError(err error) {
        if err != nil {
                fmt.Println("Fatal error ", err.Error())
        }
}

客户:

package main

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

func main() {
        if len(os.Args) != 2 {
                fmt.Println("Usage: ", os.Args[0], "host")
                os.Exit(1)
        }
        host := os.Args[1]
        conn, err := net.Dial("tcp", host+":8080")
        checkError(err)
        _, err = conn.Write([]byte("HEAD"))
        reader := bufio.NewReader(os.Stdin)
        for {
                line, err := reader.ReadString('\n')
                ftm.Println(err)
                line = strings.TrimRight(line, " \t\r\n")
                if err != nil {
                        conn.Close()
                        break

                }
        }
}
func checkError(err error) {
        if err != nil {
                fmt.Println("Fatal error ", err.Error())
        }
}

【问题讨论】:

  • checkError 函数基本上打印错误然后什么也不做。这本身就是错误的,因此它的名称具有误导性。考虑使用log.Fatal(err),它会打印错误并调用os.Exit(1)。或者将这样一个对os.Exit 的调用添加到您的错误处理函数中,并将其重命名为die 或类似的名称。
  • 不要忘记,即使没有错误,您也想关闭连接,defer conn.close() 应该在括号之外和之后,并且第一个错误子句应该是在阅读之上 - 我知道这是几年后的事情,但如果人们阅读这个。

标签: sockets go


【解决方案1】:

我不确定您是否需要解析您的地址才能收听。

你应该能够做到这一点:

listener, err := net.Listen("tcp", ":8080")

而且您似乎没有对服务器端收到的字节做任何事情(您丢弃了Read 的结果),这就解释了为什么您认为自己什么也没收到。

请注意,您的代码一次只能处理一个连接。您应该在一个新的 goroutine 中处理每个打开的连接。

这是一个相关问题中的example of client-server communication over TCP

【讨论】:

  • 进行更改后,我运行:go run fs.go 所以它给出错误:# command-line-arguments .\fs.go:10: cannot use ":8080" (type string) as在函数参数中输入 *net.TCPAddr
  • 对不起:使用的函数是Listen,而不是ListenTCP。我编辑了。 Listen 在内部调用 ListenTCP。
  • 好的,除了stackoverflow.com/questions/11202058/…,你能给我其他的例子吗
  • @KarimkhanPathan 缺少什么?是什么阻碍了你?
  • @KarimkhanPathan 我认为上面给出的示例就是您所需要的。由于您需要发送除任意字符串之外的结构化数据(用户名/密码;身份验证结果等),因此您确实需要编码器和解码器。使用编码器/解码器,您不必处理 bufio。只需使用 Encode() 和 Decode() 方法。如果您想与其他语言交互并且不想使用 Gob,只需将 Gob 替换为 Json、XML 或其他东西即可。
【解决方案2】:

我不确定您期望的确切输出是什么,因为在我看来您没有打印任何内容,只是读取客户端中的输入。正如@dystroy 指出的那样,服务器随后丢弃它收到的内容,只检查通信中的错误。

此外,您的服务器似乎应该只是坐在那里听,因为您有它在循环中这样做。如果您查看 net 包的文档,它提供了一个如何运行服务器和客户端的示例。这是我从中制作的样本,对我有用。

服务器

ln, err := net.Listen("tcp", ":8080")
// handle error
for {
    conn, err := ln.Accept()
    // handle error
    var cmd []byte
    fmt.Fscan(conn, &cmd)
    fmt.Println("Message:", string(cmd))
}

客户

conn, err := net.Dial("tcp", "127.0.0.1:8080")
// handle error
fmt.Fprintf(conn, "message\n")

编辑添加:该程序的预期结果是您运行服务器并且它处于等待状态。然后,您在另一个终端中运行客户端,该终端立即退出,但现在服务器已打印“消息:消息”。如果您再次运行客户端,服务器将再次打印相同的消息。我在我的机器上测试了这段代码(只是添加代码来响应错误),它像宣传的那样工作。

【讨论】:

    猜你喜欢
    • 2022-06-16
    • 1970-01-01
    • 2019-12-20
    • 2021-01-08
    • 2017-02-03
    • 2021-08-23
    • 2021-03-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多