2014-09-27 108 views
1

在Go中,如何做一個客戶端向服務器發送字符串,我有點困惑。當服務器運行 ioutil.ReadAll(conexao)一切都停止。在Go中的客戶端和服務器之間的通信

服務器

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)) 
+1

ReadAll從conexao讀取,直到出現錯誤或EOF並返回它讀取的數據。如果沒有錯誤或EOF,它將永遠阻止。 – siritinga 2014-09-27 17:55:25

+0

那麼,我該如何解決這個問題呢? – 2014-09-27 18:24:30

+0

您可能希望繼續閱讀直到出現錯誤(即讓客戶端關閉連接以指示它沒有更多要發送的內容) – 2014-09-27 19:07:47

回答

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和許多其他協議中添加消息成幀到請求。幀在消息信息內編碼關於消息結束位置的信息。這可以是消息長度或指示消息結束的區別字節序列。服務器被修改爲讀取消息的結尾,然後響應客戶端。

1

正確的方法是有一個特定的協議知道該怎麼讀/寫。 有關更高級協議,請查看websocket的工作方式,例如https://github.com/gorilla/websocket

更簡單的方法是使用gob.Encoder/gob.Decoder,或者如果你想要去的比較原始的,你可以使用binary.Write/binary.Read`

//採空例如:

服務器:

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)) 
相關問題