我的字节`len()`长度超出 14032 以后的就没用了,下面是代码
```golang
func (rc *rpcClient) Send(data map[string]interface{}) (string, error) {
const long = 128
// 取出的字节切片
buf := make([]byte, long)
//Buffer是一个实现了读写方法的可变大小的字节缓冲
resp := new(bytes.Buffer)
//var resp string
if rc.server.Ip == "" {
fmt.Println("服务器连接参数错误")
}
// 建立连接
conn, err := net.DialTimeout("tcp", rc.server.Ip+":"+rc.server.Port, 1*time.Second)
if err != nil {
return resp.String(), errors.New("TCP 连接超时")
}
// 异常关闭连接
defer conn.Close()
// 获取请求信息
byteData, err := json.Marshal(&data)
// 发送请求
n, err := conn.Write(byteData)
if err != nil {
return resp.String(), errors.New("TCP 发送请求失败")
}
// 读取响应
n, err = conn.Read(buf)
if err != nil {
return resp.String(), errors.New("TCP 读取响应失败")
}
resp.Write(buf[0:n])
// 续读
for n == long {
n, err = conn.Read(buf)
resp.Write(buf[0:n])
}
//fmt.Println("Reply from server ", rAddr.String(), resp)
return resp.String(), nil
}
```
不清楚是什么限制了这个字节切片的长度,如果接收的信息不是很长就没有问题。
之前 `resp` 是个 `string` 类型每次从tcp读取完字节切片数据转成字符用`resp += string(buf[0:n])`拼接在后面直至读取完毕。`long`变量设置的是 10240,一直运转没有问题,直到有一个消息信息长度为25147的时候,就开始丢字符,只能接受14032个字符。然后将`long`改小,直到128才能完成接收所有字符串(150也行)。
然后我网上查高效的字节切片转字符串使用`bytes.Buffer` 类型,就把 resp 换成了`bytes.Buffer` 类型,然后相同的问题又出现了,只能读取 14032 长度的字节切片。
我有一个PHP版本的客户端读取超长字节没有问题,每次设置的是读取 10240 长度。可以排除服务端问题。
之前使用字符串拼接 `long = 128` 也可以全部接收完成
## 问题
是golang 自身限制了字节切片长度吗?
为什么字符串拼接tcp响应的时候要把接受缓冲区设置的很小才能接受很长的字符串呢?
为什么时候用字节切片拼接统一转string的时候回出现字节切片不能接收全部字符串呢?
刚刚又调试了一下,发现了新问题就是
```golang
// 续读
for n == long {
n, err = conn.Read(buf)
resp.Write(buf[0:n])
}
```
这部分代码的问题,因为有一次读取的时候 n<long 了程序认为是 TCP 接收完成了,其实还有数据,手动设置了接受次数就全部收到了。
为什么会出现TCP没有接收完成切片却没有读满呢?
第 1 条附言 ·
找到问题了,是判断TCP接收完成的代码有问题。改成如下判断就好了
```golang
// 读取响应
_, err = io.Copy(&resp, conn)
if err != nil {
return resp.String(), err
}
```
更多评论