gpt4 book ai didi

go - 泛洪太快时服务器无法解析数据包

转载 作者:IT王子 更新时间:2023-10-29 02:24:12 26 4
gpt4 key购买 nike

这是我每秒向服务器发送过多数据包时出现的错误:

2014/11/28 12:52:49 main.go:59: loading plugin: print
2014/11/28 12:52:49 main.go:86: starting server on 0.0.0.0:8080
2014/11/28 12:52:59 server.go:15: client has connected: 127.0.0.1:59146
2014/11/28 12:52:59 server.go:43: received data from client 127.0.0.1:59146: &main.Observation{SensorId:"1", Timestamp:1416492023}
2014/11/28 12:52:59 server.go:29: read error from 127.0.0.1:59146: zlib: invalid header
2014/11/28 12:52:59 server.go:18: closing connection to: 127.0.0.1:59146

它设法解码一个数据包(有时,可能是 2 或 3 个)然后出错。这是执行泛洪的代码:

import socket
import struct
import json
import zlib
import time

def serialize(data):
data = json.dumps(data)
data = zlib.compress(data)

packet = struct.pack('!I', len(data))
packet += data

return len(data), packet

message = {
'sensor_id': '1',
'timestamp': 1416492023,
}

length, buffer = serialize([message])

client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

client.connect(('127.0.0.1', 8080))

while True:
client.send(buffer)

#time.sleep(0.0005)

当我取消注释 time.sleep() 调用时,服务器工作正常。似乎太多的数据包/每秒正在杀死服务器。为什么?

这是相关的 Go 代码。连接处理程序:

func (self *Server) handleConnection(connection net.Conn) {
for {
connection.SetReadDeadline(time.Now().Add(30 * time.Second))

observations, err := self.Protocol.Unserialize(connection)

if err != nil {
log.Printf("read error from %s: %s\n", connection.RemoteAddr(), err)

return
}
}

这是反序列化器:

// Length Value protocol to read zlib compressed, JSON encoded packets.
type ProtocolV2 struct{}

func (self *ProtocolV2) Unserialize(packet io.Reader) ([]*Observation, error) {
var length uint32

if err := binary.Read(packet, binary.BigEndian, &length); err != nil {
return nil, err
}

buffer := make([]byte, length)
rawreader := bufio.NewReader(packet)

if _, err := rawreader.Read(buffer); err != nil {
return nil, err
}

bytereader := bytes.NewReader(buffer)
zreader, err := zlib.NewReader(bytereader)

if err != nil {
return nil, err
}

defer zreader.Close()

var observations []*Observation

decoder := json.NewDecoder(zreader)

if err := decoder.Decode(&observations); err != nil {
return nil, err
}

return observations, nil
}

最佳答案

Python 脚本的客户端似乎有错误。

未检查 client.send 的返回,因此脚本无法以正确的方式处理部分写入。基本上,当套接字缓冲区已满时,只会写入部分消息,导致服务器无法解码消息。

此代码已损坏,但添加等待使其工作,因为它可以防止套接字缓冲区已满。

您可以改用 client.sendall 来确保写入操作完成。

Python 文档中的更多信息:

https://docs.python.org/2/library/socket.html

https://docs.python.org/2/howto/sockets.html#using-a-socket

现在在Go server中,也有类似的问题。文档说:

Read reads data into p. It returns the number of bytes read into p. It calls Read at most once on the underlying Reader, hence n may be less than len(p). At EOF, the count will be zero and err will be io.EOF.

rawreader.Read 调用返回的字节数可能少于您的预期。您可能希望使用 io 包的 ReadFull() 函数来确保读取完整消息。

关于go - 泛洪太快时服务器无法解析数据包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27201621/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com