2017-10-05 14 views
3

我是新來的。我一直在編碼C#,但我也需要服務器。所以我寫了一個服務器:golang net.Conn沒有可用的數據屬性

func ServeToClient(client net.Conn) { 
for { 
    fmt.Fprintln(client,"Serving you!") 
    buffer:=make([]byte,1024) 
    _, err :=bufio.NewReader(client).Read(buffer) 
    if err!=nil{ 
     fmt.Println(err) 
     client.Close() 
     fmt.Println("Disconnected duet to the error: ",err.Error()) 
     return 
    } 
    data := string(buffer) 
    fmt.Println(data) 
    command := data[0:2] 
    i,err := strconv.Atoi(command) 
    if err!=nil { 
     fmt.Println(err) 
     return 
    } 
} 

但它看到data爲:

{ 「ID」: 「009」, 「用戶名」: 「笨蛋」} ?????? ?????????????????????????????????????????????????? ?????????????????????????????????????????????????? ????????????????????????

我想這是由於字節數組超過(它是1024長度)。是否有任何財產(如C# Socket.Availabe)正確創建我的字節數組?

+0

您不應該忽略*讀取字節數,即Read方法的第一個返回值。在網絡通信中,通常您必須按塊讀取數據塊,然後組合它們以獲取整個字節流。如果您的數據採用JSON格式,請使用['json.Decoder'](https:// golang。org/pkg/encoding/json /#NewDecoder),即'decoder:= json.NewDecoder(client)',然後通過'decoder.Decode(&obj)'得到對象。 – putu

+0

Yeap。我接到你了。 – Bungler

回答

2

Read()你忽略讀入變量緩衝的字節數,在這條線據:

_, err := bufio.NewReader(client).Read(buffer)

只需添加字節的新變量ň存儲號碼:

n, err := bufio.NewReader(client).Read(buffer)

,然後你可以採取只數從緩衝區的字節具有的長度爲1024:

data := string(buffer[:n])

編輯:

其他替代方案:

+1

Yeap,這是我的情況的解決方案,但如果數據大於1024怎麼辦?我無法處理? – Bungler

+0

nope,你只能讀取前1024個字節,因爲我會使用[ioutil.ReadAll()](https://golang.org/pkg/io/ioutil/#ReadAll),或者如果你能保持這一點for循環可以讀取每個1024字節並將它們寫入[Buffer](https://golang.org/pkg/bytes/#NewBuffer),然後在for循環之外,可以將結果作爲Bytes()或String( ) –

+0

非常感謝!很棒。我也會嘗試。 – Bungler

0

添加到Yandry波索的回答是:n可能超過1024也許你不一個呼叫得到整個消息Read。 (在所有可能的網絡上)

因此,要獲得可靠的通信協議,您應該定義一些消息格式,接收方可以確定消息是否完整。

例如,您可以做一個簡單的成幀形式,並在前4個字節中發送消息的長度。然後你可以讀取,直到你得到4個字節,然後重複呼叫Read,直到你得到整個消息。

+0

清潔和高效的答案這是有益的。感謝大家。 – Bungler

相關問題