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

wangyanlb · · 4642 次点击 · 开始浏览    置顶
这是一个创建于 的主题,其中的信息可能已经有所发展或是发生改变。
朋友给了一个c++的实时行情接口,其中实时分笔成交的结构体如下 ```go typedef struct tagStockReport { WORD wDataSize; //数据长度 WORD wChecked; //数据校验 char szCode[STOCKCODESIZE]; //股票代码,以'\0'结尾 char szName[STOCKNAMESIZE]; //股票名称,以'\0'结尾 int nTradingUnit; //交易单位(每手多少股) long ltime; // UCT float fLastClose; // 昨收 float fOpen; // 今开 float fHigh; // 最高 float fLow; // 最低 float fNewPrice; // 最新 float fVolume; // 成交量 float fAmount; // 成交额 float fBuyPrice[BUYSELLCOUNT]; // 申买价1,2,3 float fBuyVolume[BUYSELLCOUNT]; // 申买量1,2,3, float fSellPrice[BUYSELLCOUNT]; // 申卖价1,2,3 float fSellVolume[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) } } ```

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

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

4642 次点击  ∙  1 赞  
加入收藏 微博
2 回复  |  直到 2015-07-04 07:07:08
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传