-1

I am trying to do something like this using Go language, UDP Client <-----> UDP Server, UDP Client sending bulk structure to UDP Server, but not able to parse at UDP Server side or vice versa. For example, the following structure sending at Client side, need to print at UDP Server side

// client Side
type Message struct {
        name   string
}
s := Message{name:"hello"}
conn, err := net.Dial("udp", "127.0.0.1:1234")
_, err = bufio.NewReader(conn).Read(s)

// server side
addr := net.UDPAddr{
 Port: 1234,
 IP: net.ParseIP("127.0.0.1"),
}
ser, err := net.ListenUDP("udp", &addr)
nBytes, remoteaddr, err := ser.ReadFromUDP(p)
fmt.Println("string : %s", p) // prints some junk

How can I achieve this? Any help is greatly appreciated. Thanks in Advance !


// Client
/*
typedef struct
{
 int    i;
 double d;
 char  s;
}Message;
*/
func main() {
 conn, err := net.Dial("udp", "127.0.0.1:5000")
 if err != nil {
    log.Fatal(err)
    return
 }
 msg, err := json.Marshal(C.Message{i: 123, d:10.5, s:'c'})
 conn.Write(msg)
 fmt.Printf("message sent")
 conn.Close()
}

// server.go
/*
typedef struct
{
 int    i;
 double d;
 char  s;
}Message;
*/
func main() {
 addr := net.UDPAddr{
 Port: 5000,
 IP:   net.ParseIP("127.0.0.1"),
 }
 s, err := net.ListenUDP("udp", &addr)
 if err != nil {
    log.Println(err)
    return
 }
 b := make([]byte, 512)
 for {
   n, rAddr, err := s.ReadFrom(b)
   var msg C.Message
   if err = json.Unmarshal(b[:n], &msg); err != nil {
      log.Println(err)
      continue
   }
   fmt.Printf("%s > %+v\n", rAddr, msg)
  }
}
ka re
  • 1
  • 1
  • 1
    How can you achieve what? What exactly isn't working? Parsing the bytes is entirely separate from UDP, do you have a question about UDP or about parsing the data? – JimB Sep 02 '21 at 16:08
  • We cannot tell from that fragment. Please update the question with a [mre]. – JimB Sep 02 '21 at 16:19
  • question is about the parsing the structure data received as UDP buffer – ka re Sep 02 '21 at 16:34
  • 2
    That is far from a complete example, and has a lot of pieces that don't make sense. A couple notes: The argument to `Read` is a byte slice, not a struct. You cannot discard a `bufio.Reader` since it may contain buffered data, though you don't ever want to use a `bufio.Reader` with a UDP connection in the first place. "prints some junk" does not tell us what you are trying to parse, and printing binary data as a string is probably not going to be useful. You are not using the `nBytes` value. You are trying to use formatting directives with `Println`, you want `Printf` functions for that. – JimB Sep 02 '21 at 16:43

1 Answers1

0

I have tried to answer your question according to what I understood.

client:

type Message struct {
    ID uint64 `json:"id"`
}

func main() {
    conn, err := net.Dial("udp", "127.0.0.1:5000")
    if err != nil {
        log.Fatal(err)
        return
    }

    // marshal and send it to udp server..
    msg, err := json.Marshal(Message{ID: 123})
    conn.Write(msg)
    conn.Close()
}

server:

type Message struct {
    ID uint64 `json:"id"`
}

func main() {
    addr := net.UDPAddr{
        Port: 5000,
        IP:   net.ParseIP("127.0.0.1"),
    }

    s, err := net.ListenUDP("udp", &addr)
    if err != nil {
        log.Println(err)
        return
    }

    b := make([]byte, 512)
    for {
        // 1. read it to byte slice
        n, rAddr, err := s.ReadFrom(b)

        // 2. unmarshal it to Message struct
        var msg Message
        if err = json.Unmarshal(b[:n], &msg); err != nil {
            log.Println(err)
            continue
        }

        fmt.Printf("%s > %+v\n", rAddr, msg)
    }
}

Sample Op: ss

The idea here is to convert the Message struct to a json encoded byte slice and send it from client. At the server side, receive it as a byte slice and then unmarshal it to the Message struct.

Tony
  • 130
  • 1
  • 1
  • 12
  • 1
    neat. Though special mention should be made to the fact that udp can drop packets and that packets size must not exceed the MTU https://stackoverflow.com/questions/1098897/what-is-the-largest-safe-udp-packet-size-on-the-internet –  Sep 05 '21 at 14:59
  • yes.. this is what i am trying to achieve.. but the UDP structure from client side should be coming as C/C++ structure? In that case, will this marshal/unmarshall will work? [Something like - A C/C++ API sending a bulk structure to a Go UDP Client and which needs to send to UDP Server C/C++ Structure ----> UDP Go Client ----> UDP Go Server] – ka re Sep 09 '21 at 05:55
  • Yes. It will work. The Unmarshal function takes JSON structure(which is independent of any language). You have to make sure that the struct tag ``json:"key"`` mentioned in your `type struct` should match the incoming JSON data. That's all. – Tony Sep 09 '21 at 06:32
  • I have tried with the help of a C structure to Go UDP [Updated the code in the original question], which is giving me default values at receiver side, as follows : 127.0.0.1:50204 > {i:0 d:0 s:0 _:[0 0 0 0 0 0 0]} – ka re Sep 09 '21 at 07:21