Comments (15)
See #573
from gnet.
func (uc *UlebCodec) ReadULEB128(conn gnet.Conn) ([]byte, error) {
bodyLen := 0
ulebLen := 1
for {
if ulebLen > 5 {
break
}
buf, err := conn.Peek(ulebLen)
// 连接中没有数据
if err != nil || len(buf) != ulebLen {
return nil, nil
}
v := 0
cc := 0
for _, b := range buf {
v += (int(b) & 0x7F) << cc
cc += 7
if b&0x80 == 0 {
bodyLen = v
break
}
}
// uleb 读取完整退出循环
if bodyLen > 0 {
break
}
ulebLen++
}
defer conn.Discard(bodyLen + ulebLen)
//等待读取bodyLen
if bodyLen > uc.readBuffSize {
return nil, fmt.Errorf("abnormal msg bodyLen:%d > readBuffSize:%d", bodyLen, uc.readBuffSize)
}
buf, _ := conn.Peek(ulebLen + bodyLen)
//PrintHex(buf[ulebLen:])
return buf[ulebLen:], nil
}
同样的代码,v1升级V2后不能正常工作,上面是V2代码,下面v1
func (uc *UlebCodec) ReadULEB128(conn gnet.Conn) ([]byte, error) {
bodyLen := 0
ulebLen := 1
for {
if ulebLen > 5 {
break
}
n, buf := conn.ReadN(ulebLen)
// 连接中没有数据
if n == 0 || n != ulebLen {
return nil, nil
}
v := 0
cc := 0
for _, b := range buf {
v += (int(b) & 0x7F) << cc
cc += 7
if b&0x80 == 0 {
bodyLen = v
break
}
}
// uleb 读取完整退出循环
if bodyLen > 0 {
break
}
ulebLen++
}
defer conn.ShiftN(bodyLen + ulebLen)
//等待读取bodyLen
if bodyLen > uc.readBuffSize {
return nil, fmt.Errorf("abnormal msg bodyLen:%d > readBuffSize:%d", bodyLen, uc.readBuffSize)
}
_, buf := conn.ReadN(ulebLen + bodyLen)
return buf[ulebLen:], nil
}
from gnet.
🤖 Non-English text detected, translating...
func (uc *UlebCodec) ReadULEB128(conn gnet.Conn) ([]byte, error) {
bodyLen := 0
ulebLen := 1
for {
ifulebLen > 5 {
break
}
buf, err := conn.Peek(ulebLen)
// There is no data in the connection
if err != nil || len(buf) != ulebLen {
return nil, nil
}
v := 0
cc := 0
for _, b := range buf {
v += (int(b) & 0x7F) << cc
cc += 7
if b&0x80 == 0 {
bodyLen = v
break
}
}
// uleb reads completely and exits the loop
if bodyLen > 0 {
break
}
ulebLen++
}
defer conn.Discard(bodyLen + ulebLen)
//Waiting to read bodyLen
if bodyLen > uc.readBuffSize {
return nil, fmt.Errorf("abnormal msg bodyLen:%d > readBuffSize:%d", bodyLen, uc.readBuffSize)
}
buf, _ := conn.Peek(ulebLen + bodyLen)
//PrintHex(buf[ulebLen:])
return buf[ulebLen:], nil
} The same code, v1 cannot work properly after upgrading to V2. The above is the V2 code, and the following v1
func (uc *UlebCodec) ReadULEB128(conn gnet.Conn) ([]byte, error) {
bodyLen := 0
ulebLen := 1
for {
ifulebLen > 5 {
break
}
n, buf := conn.ReadN(ulebLen)
// There is no data in the connection
if n == 0 || n != ulebLen {
return nil, nil
}
v := 0
cc := 0
for _, b := range buf {
v += (int(b) & 0x7F) << cc
cc += 7
if b&0x80 == 0 {
bodyLen = v
break
}
}
// uleb reads completely and exits the loop
if bodyLen > 0 {
break
}
ulebLen++
}
defer conn.ShiftN(bodyLen + ulebLen)
//Waiting to read bodyLen
if bodyLen > uc.readBuffSize {
return nil, fmt.Errorf("abnormal msg bodyLen:%d > readBuffSize:%d", bodyLen, uc.readBuffSize)
}
_, buf := conn.ReadN(ulebLen + bodyLen)
return buf[ulebLen:], nil
}
from gnet.
@panjf2000 请问这是什么问题呢
from gnet.
🤖 Non-English text detected, translating...
@panjf2000 What is the problem?
from gnet.
@panjf2000 调试感觉是buf中的数据我没有读完,然后后面就不触发OnTraffic了,v1版本正常的
from gnet.
🤖 Non-English text detected, translating...
@panjf2000 The debugging feeling is that I haven’t finished reading the data in buf, and then OnTraffic will not be triggered later. The v1 version is normal.
from gnet.
First format your code, it's unreadable.
from gnet.
@panjf2000 已经格式化了,麻烦看下上面代码呢
from gnet.
🤖 Non-English text detected, translating...
@panjf2000 It has been formatted. Please take a look at the above code.
from gnet.
One of the best practices with gnet
v2 is to keep reading and decoding packets until you reach an incomplete packet, otherwise the OnTraffic
won't be invoked again until there is new arrival of data on the socket. I think the root cause of your issue here is that gnet
v1 would loop reading and decoding packets internally while gnet
v2 wouldn't.
from gnet.
🤖 Non-English text detected, translating...
One of the best practices with v2
gnet
is to continue reading and decoding packets until an incomplete packet arrives, otherwise not callingOnTraffic
again until new data arrives on the socket. I think the root cause of your problem is thatgnet
v1 internally loops reading and decoding packets, whilegnet
v2 does not.
I can confirm that the v1 version is not reading in the inner loop, the decode code is above
This is the V1 outer code
func (s *Server) React(frame []byte, c gnet.Conn) (out []byte, action gnet.Action) {
msg := BinaryJson.DecodeGJson(frame)
if msg == nil {
action = gnet.Close
return
}
client, ok := c.Context().(*Client)
if !ok || client == nil {
return
}
task := func() {
msgType, _ := msg.GetInt("t")
switch msgType {
case rpc.PingMsg:
if err := s.Codec.WriteULEB128(client.Conn, rpc.NewPingResp()); err != nil {
client.Close()
}
client.UpdateLastPingTime()
case rpc.PongMsg:
case rpc.ReqMsg, rpc.PushMsg:
req := &rpc.Req{}
req.FromGJson(msg)
if req.Param == nil {
return
}
resp := s.Handler.HandleReq(client, req)
// Requests that do not require a reply will not be processed if the response is obtained.
if resp == nil {
return
}
// Determine whether it is an error response message
if _, ok := msg.GetString("e"); ok {
client.Close() // Wrong response information, actively close the connection
return
}
if _, ok := msg.GetString("ec"); ok {
client.Close() // Wrong response information, actively close the connection
return
}
if err := s.Codec.WriteULEB128(client.Conn, resp); err != nil {
client.Close()
}
case rpc.RespMsg:
resp := &rpc.Resp{}
resp.FromGJson(msg)
s.Handler.HandleResp(client, resp)
default:
xlog.Ins.Error(s.Handler.Name(), zap.Error(fmt.Errorf("Unknown message type: %d", msgType)))
}
}
_ = s.pool.Submit(task)
return
}
from gnet.
https://github.com/panjf2000/gnet/blob/1.x/eventloop_unix.go#L125-L126
from gnet.
https://github.com/panjf2000/gnet/blob/1.x/eventloop_unix.go#L125-L126
哦哦,了解
from gnet.
🤖 Non-English text detected, translating...
https://github.com/panjf2000/gnet/blob/1.x/eventloop_unix.go#L125-L126
Oh, I understand
from gnet.
Related Issues (20)
- [Bug]: Read returns io.ErrShortBuffer on closed connection HOT 7
- Special treatment for the first package HOT 8
- [Question]: How to shut down the started tcp server and turn off port listening? HOT 2
- [Question]: When using io.CopyBuffer(), do you need to call Flush to send the data? HOT 2
- [Bug]: Discard() panic HOT 17
- [Feature]: `io_uring` support HOT 6
- [Question]: there's gnet https server now, how to use gnet https client? HOT 1
- UDP FD handle is not released HOT 1
- [Question]: The redis server service implemented using gnet has too many read tcp i/o timeouts in the production environment. HOT 6
- [Question]: redhub upgraded to use gnet/v2 issues, seemed "stalled" HOT 1
- [Feature]: tls support HOT 5
- [Bug]: gnet.Conn.Peek crashes slice bounds out of range HOT 6
- [bug]: socket fd being reused during `OnClose()` lead to data corruption HOT 6
- [Question]: where is the example project? HOT 3
- [Question]: type engine struct { HOT 2
- [Question]: Does udp buffer support on-demand allocation? HOT 2
- [Question]: client blocks when dialing new connections HOT 19
- [Question]: How to set the client write timeout parameter? HOT 2
- [Question]: Communicate with netty HOT 2
- [Bug]: concurrent map write and read HOT 7
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from gnet.