go socket 通信 打包问题

go新手问个问题:为什么这么打包发数据,服务端错误呢,是我哪里写错了还是怎么回事?首先服务端接收的代码是C++写的。之前用PHP写的客户端发送消息是这样子的:

$body = json_encode($body);

$head = pack('IsIsIII', strlen($body), $toType, $toIp, $fromType, $fromIp, $askId, $askId2);

$dataPack = $head . $body;

socket_write($socket, $dataPack, strlen($dataPack));

然后想用go来写个demo,遇到了这个问题。
提示的错误信息:

panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xb code=0x1 addr=0x20 pc=0x331c]

goroutine 1 [running]:
panic(0x15c7c0, 0xc82000a0d0)
    /usr/local/go/src/runtime/panic.go:481 +0x3e6
main.main()
    /Users/fbbin/go/src/demo/socket_client.go:77 +0x55c
exit status 2

下面是代码

package main

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

type Protocol struct {
    length int
    toType int
    toIp int
    fromType int
    fromIp int
    askId int
    askId2 int
    body []byte
}

func (p *Protocol) pack() ([]byte, error) {
    var packetInfo *bytes.Buffer = new(bytes.Buffer)
    var err error
    err = binary.Write(packetInfo, binary.LittleEndian, p.length)
    if err != nil {
        return nil, err
    }
    err = binary.Write(packetInfo, binary.LittleEndian, p.toType)
    if err != nil {
        return nil, err
    }
    err = binary.Write(packetInfo, binary.LittleEndian, p.toIp)
    if err != nil {
        return nil, err
    }
    err = binary.Write(packetInfo, binary.LittleEndian, p.fromType)
    if err != nil {
        return nil, err
    }
    err = binary.Write(packetInfo, binary.LittleEndian, p.fromIp)
    if err != nil {
        return nil, err
    }
    err = binary.Write(packetInfo, binary.LittleEndian, p.askId)
    if err != nil {
        return nil, err
    }
    err = binary.Write(packetInfo, binary.LittleEndian, p.askId2)
    if err != nil {
        return nil, err
    }
    err = binary.Write(packetInfo, binary.LittleEndian, p.body)
    if err != nil {
        return nil, err
    }
    return packetInfo.Bytes(), nil
}

func main() {
    server := "192.168.10.110:20001"
    tcpAddr, err := net.ResolveTCPAddr("tcp4", server)
    if err != nil {
        fmt.Fprintf(os.Stderr, "Fatal error: %s", err.Error())
        os.Exit(1)
    }
    conn, err := net.DialTCP("tcp", nil, tcpAddr)
    if err != nil {
        fmt.Fprintf(os.Stderr, "Fatal error: %s", err.Error())
        os.Exit(1)
    }
    defer conn.Close()
    fmt.Println("Connect Success!")
    msgInfo := "{\"cmdid\":\"Level.Site\",\"uid\":250}"
    // 收不到该消息
    result, err := conn.Write(packet(msgInfo))
    // 能收到,但是包内容错误
    // result, err := conn.Write([]byte(msgInfo))
    fmt.Println(result, err.Error())
}

func packet(message string) []byte {
    var bodyInfo []byte = []byte(message)
    headInfo := &Protocol{
        length:len(message),
        toType:20001,
        toIp:12039112,
        fromType:20003,
        fromIp:3812912,
        askId:12122,
        askId2:12123,
        body:bodyInfo,
    }
    packInfo, err := headInfo.pack()
    if err != nil {
        return nil
    }
    return packInfo
}
查看回复