Go中客户端和服务器之间的通信

时间:2014-09-27 17:47:27

标签: go

我对Go如何在客户端向服务器发送字符串感到有些困惑。当服务器运行时 ioutil.ReadAll(conexao)一切都停止了。

服务器

    conexao, _ := listener.Accept()

    fmt.Printf("Conexão aceita %s\n", conexao.RemoteAddr())

    frase, _ := ioutil.ReadAll(conexao)
    fmt.Println("Frase recebida")

    convertida := strings.ToUpper(string(frase))

    conexao.Write([]byte(convertida))

    conexao.Close()

客户端

conexao, _ := net.DialTCP("tcp", nil, enderecoTCPServidor)

fmt.Println("Conexão Estabelecida")

conexao.Write([]byte("Gato de Botas!"))
fmt.Println("Frase enviada")

maiuscula, _ := ioutil.ReadAll(conexao)

fmt.Println("Maiuscula ",string(maiuscula))

2 个答案:

答案 0 :(得分:1)

正确的方法是使用特定的协议来知道读/写的内容。 有关更高级的协议,请检查websockets的工作方式,例如https://github.com/gorilla/websocket

更简单的方法是使用gob.Encoder / gob.Decoder,或者如果您想要更原始,可以使用binary.Write / binary.Read`

// gob例子:

服务器:

conexao, _ := listener.Accept()

fmt.Printf("Conexão aceita %s\n", conexao.RemoteAddr())
enc := gob.NewEncoder(conexao)
dec := gob.NewDecoder(conexao)
var frase string
if err := dec.Decode(&s); err != nil {
    fmt.Println("error")
}
enc.Encode(strings.ToUpper(string(frase)))
conexao.Close()

客户端:

conexao, _ := net.DialTCP("tcp", nil, enderecoTCPServidor)

fmt.Println("Conexão Estabelecida")
enc := gob.NewEncoder(conexao)
dec := gob.NewDecoder(conexao)
enc.Encode("Gato de Botas!")
var maiuscula string
dec.Decode(&maiuscula)
fmt.Println("Maiuscula ", string(maiuscula))

答案 1 :(得分:1)

即使服务器已从客户端读取完整请求,服务器也会被阻止从客户端读取数据。阻止客户端从服务器读取数据。要解决此问题,服务器必须在读取完整请求后停止读取。

解决此问题的一种方法是客户端在完成写入请求时关闭套接字的写入端。这将导致服务器在消息结束时停止读取。以下是此修补程序的一行更改:

conexao, _ := net.DialTCP("tcp", nil, enderecoTCPServidor)
fmt.Println("Conexão Estabelecida")
conexao.Write([]byte("Gato de Botas!"))
conexao.CloseWrite()   // <------- Add this line
fmt.Println("Frase enviada")
maiuscula, _ := ioutil.ReadAll(conexao)
fmt.Println("Maiuscula ",string(maiuscula))

我创建了一个有效的example on the playground

解决此问题的另一种方法是在HTTP和许多其他协议中向请求添加消息框架。框架在消息信息中编码有关消息结束的位置。这可以是消息长度或指示消息结束的区分字节序列。修改服务器以读取消息的末尾,然后响应客户端。