英文:
Communication among a client and a server in 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))
请提供你需要的翻译结果。
英文:
I'm a bit confused in how to do a client to send a string to a server, both in Go. When the server run
ioutil.ReadAll(conexao) everything stop.
Server
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()
Client
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))
答案1
得分: 1
正确的方法是使用特定的协议来确定读取/写入的内容。
对于更高级的协议,可以查看WebSockets的工作原理,例如:https://github.com/gorilla/websocket。
更简单的方法是使用gob.Encoder
/ gob.Decoder
,或者如果你想更原始一些,可以使用binary.Write
/ binary.Read
。
// gob示例:
服务器端:
conexao, _ := listener.Accept()
fmt.Printf("连接已接受 %s\n", conexao.RemoteAddr())
enc := gob.NewEncoder(conexao)
dec := gob.NewDecoder(conexao)
var frase string
if err := dec.Decode(&s); err != nil {
fmt.Println("错误")
}
enc.Encode(strings.ToUpper(string(frase)))
conexao.Close()
客户端:
conexao, _ := net.DialTCP("tcp", nil, enderecoTCPServidor)
fmt.Println("连接已建立")
enc := gob.NewEncoder(conexao)
dec := gob.NewDecoder(conexao)
enc.Encode("Gato de Botas!")
var maiuscula string
dec.Decode(&maiuscula)
fmt.Println("大写 ", string(maiuscula))
英文:
The proper way is to have a specific protocol to know what to read/write.
For a more advanced protocol check how websockets work for example, https://github.com/gorilla/websocket.
An easier way is to use gob.Encoder
/ gob.Decoder
, or if you want to go more primitive you could use binary.Write
/ binary.Read
`
// gob example:
server:
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()
client:
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))
答案2
得分: 1
服务器正在阻塞读取来自客户端的数据,即使服务器已经完整地读取了客户端的请求。客户端正在阻塞读取来自服务器的数据。为了解决这个问题,服务器必须在完整地读取请求后停止读取。
解决这个问题的一种方法是在客户端完成写入请求时,客户端关闭套接字的写入端。这将导致服务器在消息的末尾停止读取。以下是修复此问题的一行代码更改:
conexao, _ := net.DialTCP("tcp", nil, enderecoTCPServidor)
fmt.Println("Conexão Estabelecida")
conexao.Write([]byte("Gato de Botas!"))
conexao.CloseWrite() // <------- 添加这行
fmt.Println("Frase enviada")
maiuscula, _ := ioutil.ReadAll(conexao)
fmt.Println("Maiuscula ",string(maiuscula))
我在playground上创建了一个可工作的示例。
另一种解决这个问题的方法是在请求中添加消息帧,就像HTTP和许多其他协议中一样。帧在消息中编码了关于消息结束位置的信息。这可以是消息长度或指示消息结束的特殊字节序列。服务器被修改为读取到消息的末尾,然后响应客户端。
英文:
The server is blocked reading data from the client, even though the server has read the complete request from the client. The client is blocked reading data from the server. To fix this issue, the server must stop reading after the complete request is read.
One way to fix for this issue is for the client to close the write side of the socket when the client is done writing the request. This will cause the server to stop reading at the end of the message. Here's the one line change for this fix:
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))
I created a working example on the playground.
Another way to fix this issue is to add message framing to the request as in HTTP and many other protocols. Framing encodes within the message information about where the message ends. This can be a message length or a distinguished byte sequence indicating the end of the message. The server is modified to read to the end of a message and then respond to the client.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论