-
Notifications
You must be signed in to change notification settings - Fork 113
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
咨询关于conv值和stream模式的问题 #6
Comments
|
conv写死,serverchannel里根据clientsocket进行管理在大部分场景下是没有问题的。 |
Hi @szhnet
请问关于“协商”,是在什么时候/什么地方进行?因为我看demo里都是在 Hi @caoli5288 你的意思是指Server和所有Cilent都写死一个conv是没问题的吗? |
@yellowb 在kcp连接建立之前进行协商,用tcp,或者raw udp,或者其他协议如http。 仅限于kcp-netty的实现,conv写死是没问题的,因为kcp-netty根据channel.remoteAddress()保存会话。 |
是的,可以在外部用tcp或者udp进行协商。 |
=
@szhnet 作者你好,请问能给出udp协商的 例子吗 |
我也有同样的疑问,看例子中是channelActive的时候设置了conv,但在实际应用中,此时服务端并不知道这个链接对应的客户端的conv的值,想问下楼主解决了这个问题了吗? |
@medusar
你可以把这个值存在channel的metadata里。虽然我并不知道这么做有什么用。前文我已经解释过了, |
@caoli5288 恩,可能暂时我们也不会使用conv这个字段 |
发现有个 |
服务端用childOption(UkcpChannelOption.UKCP_AUTO_SET_CONV, true),客户端随机一个数值conv。只要客户端前后两次端口值和conv值不是一样即没问题。两个随机值都相同的可能性太小,理论上没问题。 |
我这边使用时是通过tcp来进行协商的,conv是服务器端分配的,通过tcp告诉客户端,所以不会重复。把UkcpChannelOption.UKCP_AUTO_SET_CONV设置为true,就是为了先暂时接受客户端传过来的conv,然后消息传到上层,由服务器端上层逻辑判断conv是否合法(也就是判断conv是否与之前分配的一致)。 |
@szhnet 恩,感觉你这种方式才是正确的。也是KCP文档里推荐的方式。但是目前我们客户端觉得这样需要一个KCP一个TCP两套逻辑,比较复杂,所以就没有搞,只用了一套方案。 |
@caoli5288 大佬,有一个小问题。只根据remoteAddress标识会话是不是无法区分同一端口的前后两次连接。或者是旧报文的影响。就像是tcp即使有socket四元组后,也还是需要通过三次握手协商seq |
我简单了解过一点kcp-go的实现。 看起来也是通过remoteaddr来保存一条会话。在此基础再比较conv的值是否变化来判断连接状态。 conv则单纯由客户端随机生成,没有协商过程。这是一种最佳实践吗?请问目前比较流行怎么用呢 |
RE: @TXYH1
所以为什么要复用同一个udp端口前后发起两次连接?
这跟写死conv一样,都是讨巧的做法。最规范的做法是在kcp连接发起前,通过别的协议(如tcp)协商出一个conv出来,但规范不代表最佳,最佳实践这东西就看场景见仁见智了。 |
@caoli5288 感谢大佬的回复
|
kcp-netty根据channel.remoteAddress()保存会话是会存在问题的吧,kcp-netty应该根据conv保存会话吧,尤其在nat port映射改变端口的情况下,只能通过conv来判断是否是同一个客户端源发出的,这块逻辑怎么考虑? |
刚接触KCP,从它的首页找到kcp-netty这个项目,使用上有几个疑惑:
1. conv值的具体用法
读了KCP的文档,个人理解conv是供服务器端识别客户端的一个标识符,毕竟UDP是非面向连接的,不知道我理解对不对?我看example里的代码EchoClientHandler和EchoServerHandler里都在channelActive函数中写死了conv的值:
kcpCh.conv(EchoClient.CONV); // set conv
而且Client和Server的conv值需要一样,否则传输数据时Server会报conv不一致的异常。这里我有个疑惑,假设有多个Client,conv值都不同,那么Server端如何在channelActive函数中知道每个Client的conv值?因为example中是hard code的
2.关于stream模式的问题,如何发送大数据
读代码时看到接收缓冲区是设定成512B
public static final int FIXED_RECV_BYTEBUF_ALLOCATOR_SIZE = 512;
测试结果是如果往channel中flush超过(512 - kcp header)字节的数据时,就会被切成多个fragment发送到对端,我看官方网页和腾讯的一篇文章,只要打开stream模式:
option(UkcpChannelOption.UKCP_STREAM, true)
对端接收到fragments后会拼装成一个完整的数据提供给应用层(不知道理解对不对)。不过我本地测试结果显示对端收到的还是一个个fragment。不过如果连续flush多个很小的数据(比如2字节),对端有时候能在一次channelRead中读到多个发送过来的数据,也就是发送方的多个小包在接收方变成一个大包了(关闭stream模式时不会有这种现象,接收方每次channelRead只能读到一次发送的数据)
请问这个行为是跟KCP的stream模式行为一致的吗?那么传输大块数据(比如64KB)时,最佳实践应该怎样?
The text was updated successfully, but these errors were encountered: