亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何高效實現json tcp server并防止socket flood?

如何高效實現json tcp server并防止socket flood?

Go
收到一只叮咚 2021-10-04 17:36:24
我正在尋找最有效的解決方案,有很多方法可以從套接字讀取數據并解碼 json。我顯然應該使用 json.Encoder 和 json.Decoder,因為它們適用于套接字的流式傳輸性質,但是我有特定的規則來防止套接字泛濫,如果有單個消息 > 5 Kb,我必須關閉連接。我的消息結構是 JSON RPC。在以下示例中,我可以檢查長度并應用策略:connbuf := bufio.NewReader(conn)msg, err := connbuf.ReadBytes('\n')if len(msg) > 5 * 1024 {    conn.Close()}...var req JSONRequesterr = json.Unmarshal(message, &req)...但是如果客戶端推送沒有分隔符的兆字節數據,這些數據將在應用程序中,在服務器斷開客戶端之前已經在 msg 變量中。相當脆弱。第二個例子使用解碼器,根本沒有機會檢查大小。dec = json.NewDecoder(conn)for {    var req JSONRequest    if err := dec.Decode(&req); err == io.EOF {        break    } else if err != nil {        log.Println(err.Error())        return err   }   ...}您可以向我建議的最佳方法是什么?謝謝。
查看完整描述

1 回答

?
紅糖糍粑

TA貢獻1815條經驗 獲得超6個贊

對于第一個示例,您可以使用ReadLine:


connbuff := bufio.NewReaderSize(conn, 5*1024)

msg, isPrefix, err := connbuff.ReadLine()

if isPrefix {

  // too long

}

...

如果isPrefix為真,則該行太長。如果您使用 a,bufio.Scanner它實際上已經具有 64kb 的最大令牌大小。


正如 Tim Cooper 和 Dave C 所說,您可以將其io.LimitedReader用于第二種情況,但是 json 解碼器有一個問題。它使用緩沖 IO,因此它將讀取第一個請求。


為了解決這個問題使用的組合io.MultiReader和io.LimitReader:


// to start with we have nothing buffered (an empty byte slice)

var buffered io.Reader = bytes.NewReader([]byte{})

for {

    // combine whatever was in buffered with conn, but only up to 5kb

    dec := json.NewDecoder(io.LimitReader(io.MultiReader(buffered, conn), 5*1024))

    var req string

    err := dec.Decode(&req)

    if err == io.EOF {

        break

    } else if err != nil {

        log.Fatalln(err)

    }

    // we probably read past the message, so save that to buffered

    buffered = dec.Buffered()

}


查看完整回答
反對 回復 2021-10-04
  • 1 回答
  • 0 關注
  • 245 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號