這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
朋友給了一個c++的即時行情介面,其中即時分筆成交的結構體如下:
1 typedef struct tagStockReport 2 { 3 WORD wDataSize; //資料長度 4 WORD wChecked; //資料校正 5 6 char szCode[STOCKCODESIZE]; //股票代號,以'\0'結尾 7 char szName[STOCKNAMESIZE]; //股票名稱,以'\0'結尾 8 9 int nTradingUnit; //交易單位(每手多少股)10 11 long ltime; // UCT12 13 float fLastClose; // 昨收14 float fOpen; // 今開15 float fHigh; // 最高16 float fLow; // 最低17 float fNewPrice; // 最新18 float fVolume; // 成交量19 float fAmount; // 成交額20 21 float fBuyPrice[BUYSELLCOUNT]; // 申買價1,2,322 float fBuyVolume[BUYSELLCOUNT]; // 申買量1,2,3,23 float fSellPrice[BUYSELLCOUNT]; // 申賣價1,2,324 float fSellVolume[BUYSELLCOUNT]; // 申賣量1,2,325 }TStockReport, *PStockReport;
我把其轉化為go對應的結構體後,通過socket 接收推送過來的行情。
幾個問題:1、c語言結構體的欄位對齊規則似乎和go語言不一樣,某些時候要在go接受的時候,補充一個空的佔位欄位。 2、如果一個結構體,裡面除了有整形、浮點外,還有一些字元類型。 就沒有辦法對結構體所有欄位統一的進行一次映射賦值。所以我只好把socket接受的資料切片逐片拼裝到結構體中,各位老大,對於這種混合型的結構體,有沒有好的統一解析socket資料流,進行賦值的方法。
上代碼:
package mainimport ( "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) }}