Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

In continuous Encode calls, the Decode peer receive zero value #207

Open
zhliner opened this issue Oct 28, 2017 · 3 comments
Open

In continuous Encode calls, the Decode peer receive zero value #207

zhliner opened this issue Oct 28, 2017 · 3 comments

Comments

@zhliner
Copy link

zhliner commented Oct 28, 2017

type Args struct {
	A, B int
}
type Request struct {
	ID     uint64
	Method string
}
// msgp EncodeMsg & DecodeMsg done.

client.go

func main() {
	conn, err := net.Dial("tcp", "127.0.0.1:1234")
	if err != nil {
		log.Fatal("dialing:", err)
	}
	ids := Request{1, "Arith.Divide"}
	args := Args{int('z'), int('a')}
	args2 := Args{int('x'), int('i')}

	msgp.Encode(conn, ids)
	// log.Println("hai")  // If this is valid, the server's result is ok.
	msgp.Encode(conn, args)
	msgp.Encode(conn, args2)
}

server.go

func main() {
	l, e := net.Listen("tcp", ":1234")
	if e != nil {
		log.Fatal("listen error:", e)
	}
	fmt.Println("start listen for client...")
	for {
		conn, err := l.Accept()
		if err != nil {
			log.Print("rpcjs.Serve: accept:", err.Error())
			return
		}
		var req Request
		var arg Args
		var arg2 Args
		msgp.Decode(conn, &req)
		fmt.Println(req)

		msgp.Decode(conn, &arg)
		fmt.Println(arg)

		msgp.Decode(conn, &arg2)
		fmt.Println(arg2)
	}
}

// Output: client first run
{1 Arith.Divide}
{0 0} or {120 105} or {122 97}
{0 0}

// Output: client second run
{1 Arith.Divide}
{122 97}
{0 0}

why?
when the log.Println("hai") is valid, the calls is ok.
// Output:
{1 Arith.Divide}
{122 97}
{120 105}

@zhliner
Copy link
Author

zhliner commented Oct 28, 2017

on Windows 10 x64 os

@shabbyrobe
Copy link
Contributor

shabbyrobe commented Oct 28, 2017

I can replicate this on OS X.

To solve your immediate problem, use the same msgp.Reader and call DecodeMsg on your structs directly:

rd := msgp.NewReader(conn)
(&req).DecodeMsg(rd)
fmt.Println(req)

(&arg).DecodeMsg(rd)
fmt.Println(arg)

(&arg2).DecodeMsg(rd)
fmt.Println(arg2)

The underlying problem with the msgp.Decode API you're using seems to be that it may create a new msgp.Reader for every call to msgp.Decode, but if multiple messages are queued on the socket when the msgp.Reader reads from it, those bytes are discarded when the call to msgp.Decode completes.

I really don't have a good idea off the top of my head how to solve that problem, but at the very least, avoiding those APIs in favour of the msgp.NewReader example I posted earlier should help get you moving.

@zhliner
Copy link
Author

zhliner commented Oct 31, 2017

@shabbyrobe
In fact, I want to use msgp as a net/rpc Codec. But directly use of DecodeMsg seem not so good.
however, thank you!!

And thanks for translate.google.com ^,^

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants