Go语言TCP连接中提取纯JSON数据的问题求助
解决TCP连接中JSON反序列化因HTTP头失败的问题
两种解决方案:
方案一:修改发送方式,直接传输纯JSON数据
curl默认会封装HTTP请求头,导致TCP连接收到的不是纯JSON。可以用以下方式发送纯JSON:
- 使用
netcat(nc)工具:
echo '{"customer":"Ada","eventtype":"BuyingApples","time":"0001-01-01T00:00:00Z","specifics":[{"Key":"Shop","Value":"Bakery"},{"Key":"Location","Value":"Downtown"},{"Key":"recommends","Value":"yes"}]}' | nc localhost 8952
- 若坚持用curl,需强制跳过HTTP协议封装(部分环境可能不兼容):
curl --raw -d '{"customer":"Ada","eventtype":"BuyingApples","time":"0001-01-01T00:00:00Z","specifics":[{"Key":"Shop","Value":"Bakery"},{"Key":"Location","Value":"Downtown"},{"Key":"recommends","Value":"yes"}]}' localhost:8952
这种方式无需修改服务端代码,TCP连接直接接收纯JSON,即可正常反序列化。
方案二:服务端解析HTTP请求,提取JSON Body
如果需要兼容curl默认的HTTP请求格式,可在服务端代码中解析HTTP头,提取Body部分的JSON:
方式1:手动解析HTTP头(轻量实现)
利用HTTP头与Body之间的\r\n\r\n分隔符,结合Content-Length读取完整Body:
import ( "bufio" "net" "strconv" "strings" ) func PushDataToBuffer(bufferedChannel chan []byte, conn net.Conn) { defer conn.Close() fmt.Println("pushing messages into buffer...") reader := bufio.NewReader(conn) contentLength := 0 // 读取HTTP头行,直到空行 for { line, err := reader.ReadString('\n') if err != nil { fmt.Println("read header error: ", err) return } trimmedLine := strings.TrimSpace(line) if trimmedLine == "" { break // 空行表示头结束 } // 提取Content-Length字段 if strings.HasPrefix(trimmedLine, "Content-Length:") { clStr := strings.TrimSpace(strings.TrimPrefix(trimmedLine, "Content-Length:")) if cl, err := strconv.Atoi(clStr); err == nil { contentLength = cl } } } // 读取指定长度的JSON Body body := make([]byte, contentLength) _, err := reader.Read(body) if err != nil { fmt.Println("read body error: ", err) return } bufferedChannel <- body }
方式2:利用Go标准库解析HTTP请求(健壮性高)
直接使用net/http包的ReadRequest函数解析完整HTTP请求,无需手动处理头信息:
import ( "bufio" "net" "net/http" ) func PushDataToBuffer(bufferedChannel chan []byte, conn net.Conn) { defer conn.Close() fmt.Println("pushing messages into buffer...") reader := bufio.NewReader(conn) req, err := http.ReadRequest(reader) if err != nil { fmt.Println("parse HTTP request error: ", err) return } defer req.Body.Close() // 读取Body内容 body := make([]byte, req.ContentLength) _, err = req.Body.Read(body) if err != nil { fmt.Println("read body error: ", err) return } bufferedChannel <- body }
修改后,后续的JSON反序列化代码即可正常处理Body中的纯JSON数据。
内容的提问来源于stack exchange,提问作者Xceptions
相关产品推荐
相关产品推荐

