go语言服务器 行情,go语言开发证券实时行情转码接口(多个坑)

朋友给了一个c++的实时行情接口,其中实时分笔成交的结构体如下

```go

typedef struct tagStockReport

{

WORDwDataSize;//数据长度

WORDwChecked;//数据校验

charszCode[STOCKCODESIZE];//股票代码,以'\0'结尾

charszName[STOCKNAMESIZE];//股票名称,以'\0'结尾

intnTradingUnit;//交易单位(每手多少股)

longltime;// UCT

floatfLastClose;// 昨收

floatfOpen;// 今开

floatfHigh;// 最高

floatfLow;// 最低

floatfNewPrice;// 最新

floatfVolume;// 成交量

floatfAmount;// 成交额

floatfBuyPrice[BUYSELLCOUNT];// 申买价1,2,3

floatfBuyVolume[BUYSELLCOUNT];// 申买量1,2,3,

floatfSellPrice[BUYSELLCOUNT];// 申卖价1,2,3

floatfSellVolume[BUYSELLCOUNT];// 申卖量1,2,3

}TStockReport, *PStockReport;

```

我把其转化为go对应的结构体后,通过socket 接收推送过来的行情。

上代码:

几个问题:1、c语言结构体的字段对齐规则似乎和go语言不一样,某些时候要在go接受的时候,补充一个空的占位字段。 2、如果一个结构体,里面除了有整形、浮点外,还有一些字符类型。 就没有办法对结构体所有字段统一的进行一次映射赋值。所以我只好把socket接受的数据切片逐片拼装到结构体中,各位老大,对于这种混合型的结构体,有没有好的统一解析socket数据流,进行赋值的方法。

```go

package main

import (

"bytes"

"encoding/binary"

"fmt"

"github.com/axgle/mahonia"

//"gopkg.in/mgo.v2"

//"gopkg.in/mgo.v2/bson"

//"log"

//"io"

"net"

"os"

//"time"

)

const (

BZ = "PUTDATA"

MongodbUrl = "localhost:27017"

)

type StockFile struct {

wDataSize uint16 //数据长度

wChecked uint16 //数据校验

szCode [12]byte //股票代码,以'\0'结尾

szName [16]int8 //股票名称,以'\0'结尾

nTradingUnit int32 //交易单位(每手多少股)

//_ int16 //补位字段

ltime int32 // UCT

fLastClose float32 // 昨收

fOpen float32 // 今开

fHigh float32 // 最高

fLow float32 // 最低

fNewPrice float32 // 最新

fVolume float32 // 成交量

fAmount float32 // 成交额

fBuyPrice [5]float32 // 申买价1,2,3,4,5

fBuyVolume [5]float32 // 申买量1,2,3,4,5

fSellPrice [5]float32 // 申卖价1,2,3,4,5

fSellVolume [5]float32 // 申卖量1,2,3,4,5

}

type StockDay struct {

wDataSize uint16 //数据长度0-1

wChecked uint16 //数据校验2-3

szCode string //股票代码,以'\0'结尾4-15

szName string //股票名称,以'\0'结尾

nTradingUnit int32 //交易单位(每手多少股)

ltime int32 // UCT

fLastClose float32 // 昨收

fOpen float32 // 今开

fHigh float32 // 最高

fLow float32 // 最低

fNewPrice float32 // 最新

fVolume float32 // 成交量

fAmount float32 // 成交额

fBuyPrice [5]float32 // 申买价1,2,3,4,5

fBuyVolume [5]float32 // 申买量1,2,3,4,5

fSellPrice [5]float32 // 申卖价1,2,3,4,5

fSellVolume [5]float32 // 申卖量1,2,3,4,5

}

func main() {

//在7076端口监听

tcpAddr, err := net.ResolveTCPAddr("tcp", ":7076")

checkError(err)

listener, err1 := net.ListenTCP("tcp", tcpAddr)

checkError(err1)

fmt.Println("服务器准备就绪")

for {

//等待客户端的连接

conn, err2 := listener.Accept()

if err != nil {

/*通常服务端为一个服务,不会因为错误而退出。出错后,继续等待下一个连接请求*/

fmt.Println(err2)

continue

}

fmt.Println("收到客户端的请求")

go ServeClient(conn)

}

}

func ServeClient(conn net.Conn) {

defer conn.Close()

defer fmt.Println("接收数据完成")

fmt.Println("开始接受数据...")

ReadHq(conn)

return

}

/*读取验证数据*/

func ReadData(conn net.Conn) string {

var data bytes.Buffer

var buf [512]byte

for {

n, err := conn.Read(buf[0:])

if err != nil {

fmt.Println(err)

return ""

}

//我们的数据以0做为结束的标记

if buf[n-1] == 0 {

//n-1去掉结束标记0

data.Write(buf[0 : n-1])

break

} else {

data.Write(buf[0:n])

}

}

return string(data.Bytes())

}

func ReadHq(conn net.Conn) {

var x StockDay

var buf [1480]byte

dec := mahonia.NewDecoder("gbk")

for {

_, err := conn.Read(buf[0:148])

if err != nil {

fmt.Println(err)

return

}

//b_buf := bytes.NewBuffer(buf[0:148])

//分拆网络传过来的数据包

binary.Read(bytes.NewBuffer(buf[0:2]), binary.LittleEndian, &x.wDataSize)

binary.Read(bytes.NewBuffer(buf[2:4]), binary.LittleEndian, &x.wChecked)

x.szCode = string(buf[4:16])

x.szName = dec.ConvertString(string(buf[16:32]))\\GBK 转 UTF8

binary.Read(bytes.NewBuffer(buf[32:36]), binary.LittleEndian, &x.nTradingUnit)

binary.Read(bytes.NewBuffer(buf[36:40]), binary.LittleEndian, &x.ltime)

binary.Read(bytes.NewBuffer(buf[40:44]), binary.LittleEndian, &x.fLastClose)

binary.Read(bytes.NewBuffer(buf[44:48]), binary.LittleEndian, &x.fOpen)

binary.Read(bytes.NewBuffer(buf[48:52]), binary.LittleEndian, &x.fHigh)

binary.Read(bytes.NewBuffer(buf[52:56]), binary.LittleEndian, &x.fLow)

binary.Read(bytes.NewBuffer(buf[56:60]), binary.LittleEndian, &x.fNewPrice)

binary.Read(bytes.NewBuffer(buf[60:64]), binary.LittleEndian, &x.fVolume)

binary.Read(bytes.NewBuffer(buf[64:68]), binary.LittleEndian, &x.fAmount)

binary.Read(bytes.NewBuffer(buf[68:88]), binary.LittleEndian, &x.fBuyPrice)

binary.Read(bytes.NewBuffer(buf[88:108]), binary.LittleEndian, &x.fBuyVolume)

binary.Read(bytes.NewBuffer(buf[108:128]), binary.LittleEndian, &x.fSellPrice)

binary.Read(bytes.NewBuffer(buf[128:148]), binary.LittleEndian, &x.fSellVolume)

//binary.Read(b_buf, binary.LittleEndian, &x) //binary.LittleEndian 是内存中的字节序的概念,就是把低字节的放到了后面。网络传输一般用BigEndian,内存字节序和cpu有关,编程时要转化。

fmt.Println(x)

//fmt.Println(b_buf)

}

return

}

func SendData(conn net.Conn, data string) {

buf := []byte(data)

/*向 byte 字节里添加结束标记*/

buf = append(buf, 0)

_, err := conn.Write(buf)

if err != nil {

fmt.Println(err)

}

}

func checkError(err error) {

if err != nil {

fmt.Println(err)

os.Exit(0)

}

}

```

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值