go - 多个串行请求导致空缓冲区
问题描述
在 osx 上的 localhost 上运行的第一个 TCP 连接始终会正确解析发送给它的二进制文件。后续请求丢失二进制数据,只看到第一个字节 [8]。我如何设置阅读器失败?
package main
import (
"fmt"
"log"
"net"
"os"
"app/src/internal/handler"
"github.com/golang-collections/collections/stack"
)
func main() {
port := os.Getenv("SERVER_PORT")
s := stack.New()
ln, err := net.Listen("tcp", ":8080")
if err != nil {
log.Fatalf("net.Listen: %v", err)
}
fmt.Println("Serving on " + port)
for {
conn, err := ln.Accept()
// defer conn.Close()
if err != nil {
log.Fatal("ln.Accept")
}
go handler.Handle(conn, s)
}
}
package handler
import (
"fmt"
"io"
"log"
"net"
"github.com/golang-collections/collections/stack"
)
func Handle(c net.Conn, s *stack.Stack) {
fmt.Printf("Serving %s\n", c.RemoteAddr().String())
buf := make([]byte, 0, 256)
tmp := make([]byte, 128)
n, err := c.Read(tmp)
if err != nil {
if err != io.EOF {
log.Fatalf("connection Read() %v", err)
}
return
}
buf = append(buf, tmp[:n]...)
}
日志:
Serving [::1]:51699
------------- value ---------------:QCXhoy5t
Buffer Length: 9. First Value: 8
Serving [::1]:51700
------------- value ---------------:
Buffer Length: 1. First Value: 8
Serving [::1]:51701
测试发送过来:
push random string:
QCXhoy5t
push random string:
GPh0EnbS
push random string:
4kJ0wN0R
解决方案
Reader的文档说:
Read reads up to len(p) bytes into p. It returns the number of bytes read (0 <= n
<= len(p)) and any error encountered. Even if Read returns n < len(p), it may use
all of p as scratch space during the call. If some data is available but not
len(p) bytes, Read conventionally returns what is available instead of waiting
for more.
因此,问题的最可能原因是 Read 正在返回可用的数据(在本例中为单个字符)。您可以通过使用ioutil.ReadAll或在循环中执行读取来解决此问题(数据被添加到缓冲区的事实使它看起来像是最初的意图),例如:
for {
n, err := c.Read(tmp)
if err != nil {
if err != io.EOF {
// Note that data might have also been received - you should process that
// if appropriate.
log.Fatalf("connection Read() %v", err)
return
}
break // All data received so process it
}
buf = append(buf, tmp[:n]...)
}
注意:不保证收到任何数据;您应该在尝试访问它之前检查长度(即buf[0]
可能会恐慌)
推荐阅读
- c# - 可以返回两个不同页面对象之一的 C# 函数
- html - 如何通过 ajax 从 url 中的谷歌图表发送值?
- javascript - 在 React 的道具更改上重新渲染子组件的最佳解决方案是什么?
- wordpress - Wordpress/ACF 将多个字段值合并为一个
- r - obj$bs_quants[[1]] 中的错误:下标超出 plot_bootstrap 函数的范围
- c# - 如何连接到数据库
- firebase - 我可以创建一个包含 fcm 消息的新活动吗?
- d3.js - d3.js 使用数据数组在线性到对数之间更改轴
- flutter - 如何将抽屉小部件放在右侧
- python - 如何在python中为单个数据框制作不同长度的列表?