kerryjiang / SuperSocket

SuperSocket is a light weight, cross platform and extensible socket server application framework.
Apache License 2.0
3.91k stars 1.15k forks source link

在2.0中,FixedHeaderPipelineFilter没有封包拆包处理 #694

Closed loveyeguo closed 2 months ago

loveyeguo commented 8 months ago

在1.6版本中自带了封包拆包处理,怎么到了2.0反而取消没有了?

loveyeguo commented 8 months ago

大佬看到麻烦回复一下,挺急的,我继承了“FixedHeaderPipelineFilter”,但是这个类没有做封包拆包处理,原来我用1.6版本的时候是有这个方法的。还是说.netcore版本的已经不需要封包拆包了?

chucklu commented 8 months ago

Please check this sample https://github.com/kerryjiang/SuperSocket/blob/27553dccc65ad88915343ba873a93f697b15efcb/test/SuperSocket.Tests/FixedHeaderProtocolTest.cs#L37

You need define the header size, and DecodePackage by yourself

loveyeguo commented 8 months ago

这个我知道,原来1.6有这个封包处理,现在2.0没有了,然后现在只要中间报文有一个错了,后面的就全部解析失败了

chucklu commented 8 months ago

The Filter method of IPipelineFilter is processed here https://github.com/kerryjiang/SuperSocket/blob/27553dccc65ad88915343ba873a93f697b15efcb/src/SuperSocket.Channel/PipeChannel.cs#L467 The logic you mentioned should be processed here If you think there is a problem, you could try to debug it

loveyeguo commented 8 months ago

嗯,我大概找到了这个部分,但是好像这个部分有点问题。譬如我现在有一个头部固定是10个字节的数据,然后通过GetBodyLengthFromHeader方法获取到总数据包是50个。 但实际我只传了48个字节,然后我第二次再传2个字节。这里程序没有很好的拼接成完整的50个字节。

chucklu commented 8 months ago

the current pipeline filter needs more data to process https://github.com/kerryjiang/SuperSocket/blob/27553dccc65ad88915343ba873a93f697b15efcb/src/SuperSocket.Channel/PipeChannel.cs#L498

This part should work fine, however you can debug and check

loveyeguo commented 8 months ago

感谢,我正在调试中...

loveyeguo commented 8 months ago

我大概知道原因了,我第一次传了一个残缺的包后,后面没有紧跟一个正确的包,然后过了一会,又来一个完整的包,这个时候会拼接到第一个包,然后导致后面所有的数据包全部错了。请问哪个机制可以判定,譬如如果过了一秒以后,我将丢弃缓存中的包,然后重新解析下一个新的包?

loveyeguo commented 8 months ago

丢弃缓存中残缺的包,写在哪里比较好?用哪个方法

loveyeguo commented 8 months ago

大概需要一个机制,过了单位时间没有收到新数据包,则在下一次收到数据包后将原来缓存数据包清空掉

loveyeguo commented 8 months ago

我想请教下一个问题,针对FixedHeaderPipelineFilter,是不是每一个session都是一个单独的实例?

chucklu commented 8 months ago

丢弃缓存中残缺的包,写在哪里比较好?用哪个方法

Not sure, have no experience about this, previously I think the lib could handle this automatically. Maybe @kerryjiang can help

loveyeguo commented 8 months ago

嗯,我自己研究一下吧,但是这个很有必要。不然只要有一个包没有发准确,后面所有拼接的包会全错

chucklu commented 8 months ago

我想请教下一个问题,针对FixedHeaderPipelineFilter,是不是每一个session都是一个单独的实例?

https://github.com/kerryjiang/SuperSocket/blob/27553dccc65ad88915343ba873a93f697b15efcb/src/SuperSocket.Server/SuperSocketService.cs#L170 each session maps to a channel, every channel should with its own PipelineFilter

loveyeguo commented 8 months ago

image

loveyeguo commented 8 months ago

主要应该是这里了,但是我写了很久没写好,如何实现,若两个包的接收时间超过某个单位时间,则舍弃掉旧包,只处理最新收到的数据包?

loveyeguo commented 8 months ago

不然这里会存在一个致命bug,如果有一个错误数据包被纳入缓存中,那么接下来所有的正确数据包均会解析失败

loveyeguo commented 8 months ago

@kerryjiang

loveyeguo commented 8 months ago

跪求啊,一下午了没写出来

xyhere2002 commented 7 months ago

我遇到了同样的问题,现在解决的思路有两个,如果错误的包是固定的,可以单独把这种包排除掉,如果不是固定的,则只有先缓存所有包,然后自己用代码从缓存的包里解析出正确的数据

kerryjiang commented 6 months ago

如果客户端发送数据不遵守协议,我一般会建议断开连接。