事实上tcp包你是不需要判断哪个是包尾的,他发送都是一次一个包这样的
for {
i, err := instance.TcpConnect.Read(b)
log.Printf("从 %s 收到结果:%x\n", ipStr, b[0:i])
messageHandle(instance, b[0:i])
if err != nil {
log.Printf("%sTcp读取错误\n", ipStr)
}
}
golang 调用odoo xml-rpc 工程目录testexample里面有个例子
golang post 请求服务器 可以用来查看xml-rpc的请求 go请求xml-rpc
-
BW800用的wifi模块为esp8266
-
BW800作为客户端,输入服务器端的ip 端口号(9999)。
fmt.Println("A client connected : " + tcpConn.RemoteAddr().String())
var mycontain = &BW800Tcp.Bw800Container{}
mycontain.AddBW800(tcpConn)
mes := []byte{0x8A, 0x9B, 0x02, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x2E}
mycontain.BW800S[0].WriteChan <- mes
fmt.Println(<-mycontain.BW800S[0].ReadChan)
一个tcp连接过来后创建一个实例并加到一个容器内,该实例会自动回复心跳包和登录包,如果要发送一些协议报文,只要向这个实例里面的WriteChan写入要发送的报文 在ReadChan里面接收返回的报文就行
-
BW800里面输入服务器ip 端口号。
-
服务器会收到BW800发过来的登录报文,服务器必须回复该报文,如果不回复3次,BW800会重新发起一个tcp连接。
-
BW800收到登录回复报文后,不再发送登录报文,开始发送心跳包,心跳包也要回复,回复内容可以为任意内容。如果3次没回复后会重新发送登录报文。在这里是收到心跳包后直接发送命令,更新结构体
-
有一个定时任务(每次收到心跳包后运行),调用odoo模块的函数将数据存储到odoo的数据库中。
-
心跳包启动的定时任务中,每一次读取10条记录,详细记录3200条最多,那么要读320次重复发送后一个循环,如果是日记录64条最多,那么也是如此。如果读到剩余记录了那么就重置,重第1条再次读取再读到最后一条。
- 结构体 容器类BW800Container.go 用来存放BW800的实例BW800Instance.go,具有方法
type Bw800Container struct {
BW800S []*BW800Instance //存放BW800的每一个连接实例
}
func (b *Bw800Container) AddBW800(conn *net.TCPConn) { //向容器中添加BW800的实例
-
结构体 BW800Instance 成员变量 WriteChan chan []byte //用于存放将要发送的命令 ReadChan chan []byte //用于存放接收到的命令,如果是心跳包,登录包不算会自动回复
将要发送的命令放到WriteChan中就可以在ReadChan中读取到返回的包
1.将要发送的结构体转为json发送出去。
2.go要发送过去的json格式里面的变量类型应该与odoo数据库里面的类型保持一致