1.客户端代码:

package main

import(
    "golang.org/x/net/websocket"
    "fmt"
    "net/http"
    "flag"
)

type WSServer struct {
    ListenAddr string
}

func (this *WSServer)handler(conn *websocket.Conn){
    fmt.Printf("a new ws conn: %s->%s\n", conn.RemoteAddr().String(), conn.LocalAddr().String())
    var err error
    for {
        var reply string
        err = websocket.Message.Receive(conn, &reply)
        if err != nil {
            fmt.Println("receive err:",err.Error())
            break
        }
        fmt.Println("Received from client: " + reply)
        if err = websocket.Message.Send(conn, reply); err != nil {
            fmt.Println("send err:", err.Error())
            break
        }
    }
}
func (this *WSServer)start()(error){
    http.Handle("/ws", websocket.Handler(this.handler))
    fmt.Println("begin to listen")
    err := http.ListenAndServe(this.ListenAddr, nil)
    if err != nil {
        fmt.Println("ListenAndServe:", err)
        return err
    }
    fmt.Println("start end")
    return nil
}

func main(){
    addr  := flag.String("a", "0.0.0.0:6610", "websocket server listen address")
    flag.Parse()
    wsServer := &WSServer{
        ListenAddr : *addr,
    }
    wsServer.start()
    fmt.Println("------end-------")
}
 

2.服务器端代码

package main

import (
    "flag"
    "fmt"
    "time"
    "golang.org/x/net/websocket"
)

var addr = flag.String("addr", "127.0.0.1:6610", "http service address")

func main() {
    flag.Parse()

    url := "ws://"+ *addr + "/ws"
    origin := "test://1111111/"
    ws, err := websocket.Dial(url, "", origin)
    if err != nil {
        fmt.Println(err)
    }
    go timeWriter(ws)

    for {
        var msg [512]byte
        _, err := ws.Read(msg[:])//此处阻塞,等待有数据可读
        if err != nil {
            fmt.Println("read:", err)
            return
        }

        fmt.Printf("received: %s\n", msg)
    }
}

func timeWriter(conn *websocket.Conn) {
    for {
        time.Sleep(time.Second * 2)
        websocket.Message.Send(conn, "hello world")
    }
}
 

需要注意的是origin必须以“http://1111111/” 这种标准的URI格式,否则报错“invalid URI for r.equest”。 

还需要注意的是,客户端和服务器端ip地址应该是你的本机地址,端口号一样。服务器端ip地址可以写成0.0.0.0

本地客户端服务器端通信,需要在dos命令行中敲入route add 本机ip mask 255.255.255.255 网关ip metric 1

3 .抓包

首先,运行客户端程序,生成可执行文件exe。

其次,运行服务器端程序,准备监听客户端的请求。

然后,运行客户端程序,准备用wireshark进行抓包。

进入wireshark,在过滤器中填入ip.addr==本机地址ip and tcp.port=6610 进行过滤,之后捕获分组即可。其中可以看到,tcp的三次握手,http的请求。之后就是发送的tcp和websocket包,左键点击追踪流即可查询到包里的发送内容。