执行:服务器应阻塞,直到收到来自客户端的消息

I'm building some server/client application in Go (the language is new to me). I searched a lot and read a whole bunch of different examples but there is still one thing I can't find. Lets say I have a single server client up and running. The client will send some kind of a message to the server and vice versa. Encoding and decoding is done by the package gob.

This example is not my application, it is only a quick example:

package main

import (
    "bytes"
    "encoding/gob"
    "fmt"
    "log"
)

type Message struct {
    Sender   string
    Receiver string
    Command  uint8
    Value    int64
}

func (message *Message) Set(sender string, receiver string, command uint8, value int64) *Message {

    message.Sender = sender
    message.Receiver = receiver
    message.Command = command
    message.Value = value

    return message
}

func main() {

    var network bytes.Buffer // Stand-in for a network connection

    enc := gob.NewEncoder(&network) // Will write to network.
    dec := gob.NewDecoder(&network) // Will read from network.

    message := new(Message).Set("first", "second", 10, -1)

    err := enc.Encode(*message) // send message
    if err != nil {
        log.Fatal("encode error:", err)
    }

    var m Message
    err = dec.Decode(&m) // receice message

    if err != nil {
        log.Fatal("decode error:", err)
    }

    fmt.Printf("%q %q %d %d
", m.Sender, m.Receiver, m.Command, m.Value)
}

This works fine, but I want the server to block until a new message is received so I can put the receiving process inside a infinite for loop inside a goroutine.

Something like that:

for {
    // The server blocks HERE until a message from the client is received

    fmt.Println("Received message:")

    // Decode the new message
    var m Message
    err = dec.Decode(&m) // receice message

    if err != nil {
        log.Fatal("decode error:", err)
    }

    fmt.Printf("%q %q %d %d
", m.Sender, m.Receiver, m.Command, m.Value)
}

The gob decoder blocks until it has read a full message or there's an error. The read loop in the question works as is.

working example on the playground

add a length header to the raw tcp stream.

that means, send a 4-bytes-length-header information to server before send the real load. and in server side read 4 bytes, allocate buffer, full read total message, and finally decode.

assume you have a tcp connection conn, in server side we could have:

func getInt(v []byte) int {
    var r uint
    r = 0
    r |= uint(v[0]) << 24
    r |= uint(v[1]) << 16
    r |= uint(v[2]) << 8
    r |= uint(v[3]) << 0
    return int(r)
}

buf := make([]byte, 4)
_, err := io.ReadFull(conn, buf)
if err != nil {
    return
}

length := getInt(buf)
buf = make([]byte, length)
_, err = io.ReadFull(conn, buf)
if err != nil {
    return
}
//do gob decode from `buf` here

you may know client side refer the the server side source I think.