Not a Name
Not a Name

Reputation: 1003

How do you use the net functions effectively in Go?

For example, having basic packet protocol, like:

[packetType int][packetId int][data []byte]

And making a client and server doing simple things with it (egx, chatting.)

Upvotes: 3

Views: 209

Answers (2)

kostix
kostix

Reputation: 55443

Check out Jan Newmarch's "Network programming with Go".

Upvotes: 3

Evan Shaw
Evan Shaw

Reputation: 24547

Here's a client and server with sloppy panic error-handling. They have some limitations:

  • The server only handles one client connection at a time. You could fix this by using goroutines.
  • Packets always contain 100-byte payloads. You could fix this by putting a length in the packet somewhere and not using encoding/binary for the entire struct, but I've kept it simple.

Here's the server:

package main

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

type packet struct {
    // Field names must be capitalized for encoding/binary.
    // It's also important to use explicitly sized types.
    // int32 rather than int, etc.
    Type int32
    Id   int32
    // This must be an array rather than a slice.
    Data [100]byte
}

func main() {
    // set up a listener on port 2000
    l, err := net.Listen("tcp", ":2000")
    if err != nil {
        panic(err.String())
    }

    for {
        // start listening for a connection
        conn, err := l.Accept()
        if err != nil {
            panic(err.String())
        }
        handleClient(conn)
    }
}

func handleClient(conn net.Conn) {
    defer conn.Close()

    // a client has connected; now wait for a packet
    var msg packet
    binary.Read(conn, binary.BigEndian, &msg)
    fmt.Printf("Received a packet: %s\n", msg.Data)

    // send the response
    response := packet{Type: 1, Id: 1}
    copy(response.Data[:], "Hello, client")
    binary.Write(conn, binary.BigEndian, &response)
}

Here's the client. It sends one packet with packet type 0, id 0, and the contents "Hello, server". Then it waits for a response, prints it, and exits.

package main

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

type packet struct {
    Type int32
    Id   int32
    Data [100]byte
}

func main() {
    // connect to localhost on port 2000
    conn, err := net.Dial("tcp", ":2000")
    if err != nil {
        panic(err.String())
    }
    defer conn.Close()

    // send a packet
    msg := packet{}
    copy(msg.Data[:], "Hello, server")
    err = binary.Write(conn, binary.BigEndian, &msg)
    if err != nil {
        panic(err.String())
    }

    // receive the response
    var response packet
    err = binary.Read(conn, binary.BigEndian, &response)
    if err != nil {
        panic(err.String())
    }
    fmt.Printf("Response: %s\n", response.Data)
}

Upvotes: 5

Related Questions