Go 如何编写 Swoole 的 客户端?

junliuxian · 2017-11-14 11:06:57 · 1107 次点击 · 大约8小时之前 开始浏览    置顶
这是一个创建于 2017-11-14 11:06:57 的主题,其中的信息可能已经有所发展或是发生改变。

我尝试用 net.Dial 去编写 TCP 客户端。可是在读取数据的时候我遇到问题了。 read 的时候,需要指定字节长度,能否不指定呢?新手刚接触,还望指点迷津~

感激不尽


有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1107 次点击  
加入收藏 微博
7 回复  |  直到 2017-11-15 13:52:29
admin87
admin87 · #1 · 7年之前

read可以不指定吧。看返回值,读取多少。

admin87
admin87 · #2 · 7年之前

//处理连接Connection func handleReceive(conn net.Conn) { buf:=new(Buffer) buffer := make([]byte, 2048) tick:=time.Tick(time.Millisecond*200) for { <-tick n, err := conn.Read(buffer) if err != nil { buf.Reset() delete(clients,conn.RemoteAddr().String()); Log(conn.RemoteAddr().String(), "Connection Error:", err) return } buf.Write(buffer[:n]) //解析数据包 //读取定长8个字节i pLength:=8 pBuf:=make([]byte,pLength) for buf.Len()>=pLength{ if _,err:= buf.Read(pBuf,pLength);err==nil{ msg:=string(pBuf) Log(conn.RemoteAddr().String(), "Receive Data:\n",msg ) //conn.Write([]byte("ClientSend:"+msg)) } } } }

admin87
admin87 · #3 · 7年之前

//处理连接Connection func handleReceive(conn net.Conn) {

buf:=new(Buffer)
buffer := make([]byte, 2048)
tick:=time.Tick(time.Millisecond*200)
for {
    <-tick
    n, err := conn.Read(buffer)
    if err != nil {
        buf.Reset()
        delete(clients,conn.RemoteAddr().String());
        Log(conn.RemoteAddr().String(), "Connection Error:", err)
        return
    }
    buf.Write(buffer[:n])
    //解析数据包
    //读取定长8个字节i
    pLength:=8
    pBuf:=make([]byte,pLength)
    for buf.Len()>=pLength{
        if _,err:= buf.Read(pBuf,pLength);err==nil{
            msg:=string(pBuf)
            Log(conn.RemoteAddr().String(), "Receive Data:\n",msg )
            //conn.Write([]byte("ClientSend:"+msg))
        }
    }
}

}

admin87
admin87 · #4 · 7年之前

不会发代码,但发现回个车就行了。

admin87
admin87 · #5 · 7年之前

SORRY我好像看错了,不是SOCKET

junliuxian
junliuxian · #6 · 7年之前
admin87admin87 #5 回复

SORRY我好像看错了,不是SOCKET

感谢你的回答

我的问题是这样的。我想用 GO TCP 连接 Swoole 服务端。但是在传输数据的时候遇到问题了。我弄了个 EOF 协议头。但我想学习了解下 如何使用 固定包头+包体协议 ,也就是 GO 这边组包和解包 是根据包头来判断的

marlonche
marlonche · #7 · 7年之前

下面是一段服务端从客户端接收数据包的简化代码:

func (self *ClientConn) recv() {
        var err error
        defer func() {
                if e := recover(); e != nil {
                }
                self.Close(false)
        }()

        _buf := make([]byte, 1)
        buf := make([]byte, 0)
        var bufLen uint32 = 0
        var readSize int
        var packet *pb.Packet
        for {
                deadline := time.Now().Add(hb * time.Second)
                self.conn.SetReadDeadline(deadline)
                readSize, err = self.conn.Read(_buf)
                if err != nil {
                        return
                }
                if readSize <= 0 {
                        continue
                }
                buf = append(buf, _buf[:readSize]...)
                bufLen += uint32(readSize)
                for {
                        if bufLen < pb.DATA_LEN_HEAD {
                                break
                        }
                        packLen := (uint32)(pb.BytesToUint16(buf[:pb.DATA_LEN_HEAD]))
                        if pb.HB_FLAG == packLen {
                                if err = self.onHeartBeat(); err != nil {
                                        return
                                }
                                buf = buf[pb.DATA_LEN_HEAD:]
                                bufLen -= pb.DATA_LEN_HEAD
                                continue
                        }
                        if packLen > pb.DATA_LEN_LIMIT || packLen < pb.DATA_LEN_HEAD {
                                err = fmt.Errorf("invalid packet length:%v, buf:%v, conn:%p", packLen, buf, self)
                                return
                        }
                        if bufLen < packLen {
                                break
                        }
                        packetData := buf[:packLen]
                        packet, err = self.unmarshalPacket(packetData)
                        if err != nil {
                                return
                        }
                        if err = self.OnRecvPacket(packet); err != nil {
                                return
                        }
                        buf = buf[packLen:]
                        bufLen -= packLen
                        continue
                }
        }
}
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传