8

I'm new to Golang and am using the "Server" code here as a starting point: http://www.golang-book.com/13/index.htm#section7

I've attempted to use JSON instead of Gob decoding (since I am required to write the client in C#), and I'm sending the JSON TCP data client data in a separate script from the code below.

I'm stuck on the part where I'm actually receiving the JSON TCP data and storing it in a variable for it to be decoded. It looks like I can decode it with json.Unmarshal, but I can't find any examples where json.Unmarshal is being used to decode TCP data. I can only find examples where json.Unmarshal is being used to decode JSON strings.

My code is below:

package main

import (
  "encoding/json"
  "fmt"
  "net"
)

type coordinate struct {
  X float64 `json:"x"`
  Y float64 `json:"y"`
  Z float64 `json:"z"`
}

func server() {
  // listen on a port
  ln, err := net.Listen("tcp", ":9999")
  if err != nil {
    fmt.Println(err)
    return
  }
  for {
    // accept a connection
    c, err := ln.Accept()
    if err != nil {
      fmt.Println(err)
      continue
    }
    // handle the connection
    go handleServerConnection(c)
  }
}

func handleServerConnection(c net.Conn) {
  // receive the message
  var msg coordinate

Stuck on the line below. What could I set the rawJSON variable equal to?

  err := json.Unmarshal([]byte(rawJSON), &msg)
  if err != nil {
    fmt.Println(err)
  } else {
    fmt.Println("Received", msg)
  }

  c.Close()
}

func main() {
  go server()

  //let the server goroutine run forever
  var input string
  fmt.Scanln(&input)
}
4
  • You need to read the data from the connection obviously. What is the message framing that your client is going to use? Commented May 12, 2015 at 12:46
  • Yeah, I am trying to read the data from the connection. Here is the code I am sending from the client (written in Ruby). pastebin.com/vkUy0hta I have verified that the tcp socket is established and the golang server is receiving the packets. I just can't figure out how to read the actual data being sent and decode the JSON. Commented May 12, 2015 at 12:51
  • Why not just use http which sets up the framing for you, and allows you to any client library you wish? Closing the connection after each message is going to be very inefficient. Commented May 12, 2015 at 13:07
  • Woops, I didn't realize I was closing the connection after each message. My goal is to create an MMORPG game where the client sends the server a constant stream of coordinate/rotation TCP data, so I think TCP would be the best protocol to use. Commented May 12, 2015 at 13:12

1 Answer 1

13

You can patch a json.Decoder directly to the connection:

func handleServerConnection(c net.Conn) {

    // we create a decoder that reads directly from the socket
    d := json.NewDecoder(c)

    var msg coordinate

    err := d.Decode(&msg)
    fmt.Println(msg, err)

    c.Close()

}
Sign up to request clarification or add additional context in comments.

3 Comments

Decoder can read multiple messages, in the same way that Encoder writes multiple messages. They use a simple newline delimiter between objects.
This code/explanation helps me a lot, thank you. My goal is to create a client that sends coordinates in an online game to a Golang server, so I do need to send constant streams of data. I'll look into the EOF some more, thanks.
@jimb thanks, I wasn't aware of that. I'll change my answer when I'm not on my phone :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.