你如何在Go中有效地使用网络功能?

时间:2011-09-22 15:00:17

标签: network-programming go

例如,具有基本数据包协议,例如:

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

让客户端和服务器用它做简单的事情(egx,聊天。)

2 个答案:

答案 0 :(得分:5)

这是一个客户端和服务器,带有草率的恐慌错误处理。他们有一些限制:

  • 服务器一次只处理一个客户端连接。你可以通过使用goroutines解决这个问题。
  • 数据包始终包含100字节的有效负载。您可以通过在数据包中放置一个长度来解决这个问题,而不是对整个结构使用编码/二进制文件,但我保持简单。

这是服务器:

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)
}

这是客户。它发送一个数据包类型为0,ID为0的数据包,内容为“Hello,server”。然后它等待响应,打印并退出。

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)
}

答案 1 :(得分:3)

查看Jan Newmarch的{​​{3}}。