看帖神器
未名空间
追帖动态
头条新闻
每日新帖
最新热帖
新闻存档
热帖存档
文学城
虎扑论坛
未名空间
北美华人网
北美微论坛
看帖神器
登录
← 下载
《看帖神器》官方
iOS App
,体验轻松追帖。
一个关于Netty client program 的问题
查看未名空间今日新帖
最新回复:2020年2月15日 11点54分 PT
共 (5) 楼
返回列表
订阅追帖
只看未读
更多选项
阅读全帖
只看图片
只看视频
查看原帖
W
WhereIsMyGCU
4 年多
楼主 (未名空间)
这个版上有用过Netty的牛人吗?
现在在用Netty 开发一个小的客户和服务器程序。这两个程序的通信协议是用TLS。
TLS是channelpipeline里面的第一个handler:
pipe.addFirst("SSL", sslHandler)。现在这两个程序可以互相发送/接收数据。
我的问题是关于客户端 (client, not server)的早期数据发送。在客户端程序里面,
channelActive(ChannelHandlerContext ctx)被调用以后, ctx就可以被拿来用了。
理论上这时就可以发送数据了。但是实践发现, 这时的TCP连接是准备好了,但是TLS
的handshake 还没有完成。 如果这时发送数据,数据会无声无息的丢掉。这个很烦人。
TLS的handshake在channelRead(ChannelHandlerContext ctx, Object msg)被调用的时候(即收到一个数据包时)是完成了的。 但是这个程序是客户端,它应当先发送数据给
服务器(而不是等待数据)。为了防止发送数据丢失, 在客户端程序里面, 我试图先检测TLS的状态:
SSLEngine sslEngine = sslhandler.engine();
HandshakeStatus sslStatus = sslEngine.getHandshakeStatus();
if (sslStatus == HandshakeStatus.FINISHED || sslStatus == HandshakeStatus.
NEED_WRAP || sslStatus == HandshakeStatus.NOT_HANDSHAKING) {
...
发现这个方法不是很理想, 有时还是丢数据。反而是加一个固定的延时等待handshake结束更保险些。但是固定延时也不完全保险,特别是客户端必须同时开很多连接到很多服务器的时候。
这个问题有没有更好的解决办法? (我的Netty版本是Netty 4.1.36-Final)
谢谢!
T
TeacherWei
4 年多
2 楼
没用过netty。
但是明显你逻辑有问题
只有sslStatus == HandshakeStatus.FINISHED 以后,你才能读写socket。
其他状态你只能等。
netty肯定有sslStatus的callback。
你想想看,这么大的项目,怎么可能像你说的那样扯蛋?
f
fantasist
4 年多
3 楼
需要的大概是这个:https://netty.io/4.0/api/io/netty/handler/ssl/SslHandler.
html#handshakeFuture--
现在高级的语言基本都不用你自己检查状态,“HandshakeStatus.FINISHED”这种东西是implementation detail,用户自己引用不仅容易出错,版本升级还会带来兼容性问
题。callback是王道,一般只需要自己定义onSuccess和onFailure。Modern C++都这么写了,效率高很多。
n
netghost
4 年多
4 楼
不熟悉java,但是你總得connect吧。connect呢?
【 在 WhereIsMyGCU (LifeIsTough) 的大作中提到: 】
: 这个版上有用过Netty的牛人吗?
: 现在在用Netty 开发一个小的客户和服务器程序。这两个程序的通信协议是用TLS。 : TLS是channelpipeline里面的第一个handler:
: pipe.addFirst("SSL", sslHandler)。现在这两个程序可以互相发送/接收数据。
: 我的问题是关于客户端 (client, not server)的早期数据发送。在客户端程序里面,
: channelActive(ChannelHandlerContext ctx)被调用以后, ctx就可以被拿来用了。
: 理论上这时就可以发送数据了。但是实践发现, 这时的TCP连接是准备好了,但是
TLS
: 的handshake 还没有完成。 如果这时发送数据,数据会无声无息的丢掉。这个很烦
人。
: TLS的handshake在channelRead(ChannelHandlerContext ctx, Object msg)被调用的时
: 候(即收到一个数据包时)是完成了的。 但是这个程序是客户端,它应当先发送数据给
: ...................
W
WhereIsMyGCU
4 年多
5 楼
多谢。
你的这个是正解,跟Netty的event-driven 的设计思路相符。程序改正后表现好很多了。
【 在 fantasist (一) 的大作中提到: 】
: 需要的大概是这个:https://netty.io/4.0/api/io/netty/handler/ssl/SslHandler.
: html#handshakeFuture--
: 现在高级的语言基本都不用你自己检查状态,“HandshakeStatus.FINISHED”这种东西
: 是implementation detail,用户自己引用不仅容易出错,版本升级还会带来兼容性问
: 题。callback是王道,一般只需要自己定义onSuccess和onFailure。Modern C++都这么
: 写了,效率高很多。
请输入帖子链接
收藏帖子
这个版上有用过Netty的牛人吗?
现在在用Netty 开发一个小的客户和服务器程序。这两个程序的通信协议是用TLS。
TLS是channelpipeline里面的第一个handler:
pipe.addFirst("SSL", sslHandler)。现在这两个程序可以互相发送/接收数据。
我的问题是关于客户端 (client, not server)的早期数据发送。在客户端程序里面,
channelActive(ChannelHandlerContext ctx)被调用以后, ctx就可以被拿来用了。
理论上这时就可以发送数据了。但是实践发现, 这时的TCP连接是准备好了,但是TLS
的handshake 还没有完成。 如果这时发送数据,数据会无声无息的丢掉。这个很烦人。
TLS的handshake在channelRead(ChannelHandlerContext ctx, Object msg)被调用的时候(即收到一个数据包时)是完成了的。 但是这个程序是客户端,它应当先发送数据给
服务器(而不是等待数据)。为了防止发送数据丢失, 在客户端程序里面, 我试图先检测TLS的状态:
SSLEngine sslEngine = sslhandler.engine();
HandshakeStatus sslStatus = sslEngine.getHandshakeStatus();
if (sslStatus == HandshakeStatus.FINISHED || sslStatus == HandshakeStatus.
NEED_WRAP || sslStatus == HandshakeStatus.NOT_HANDSHAKING) {
...
发现这个方法不是很理想, 有时还是丢数据。反而是加一个固定的延时等待handshake结束更保险些。但是固定延时也不完全保险,特别是客户端必须同时开很多连接到很多服务器的时候。
这个问题有没有更好的解决办法? (我的Netty版本是Netty 4.1.36-Final)
谢谢!
没用过netty。
但是明显你逻辑有问题
只有sslStatus == HandshakeStatus.FINISHED 以后,你才能读写socket。
其他状态你只能等。
netty肯定有sslStatus的callback。
你想想看,这么大的项目,怎么可能像你说的那样扯蛋?
需要的大概是这个:https://netty.io/4.0/api/io/netty/handler/ssl/SslHandler.
html#handshakeFuture--
现在高级的语言基本都不用你自己检查状态,“HandshakeStatus.FINISHED”这种东西是implementation detail,用户自己引用不仅容易出错,版本升级还会带来兼容性问
题。callback是王道,一般只需要自己定义onSuccess和onFailure。Modern C++都这么写了,效率高很多。
不熟悉java,但是你總得connect吧。connect呢?
【 在 WhereIsMyGCU (LifeIsTough) 的大作中提到: 】
: 这个版上有用过Netty的牛人吗?
: 现在在用Netty 开发一个小的客户和服务器程序。这两个程序的通信协议是用TLS。 : TLS是channelpipeline里面的第一个handler:
: pipe.addFirst("SSL", sslHandler)。现在这两个程序可以互相发送/接收数据。
: 我的问题是关于客户端 (client, not server)的早期数据发送。在客户端程序里面,
: channelActive(ChannelHandlerContext ctx)被调用以后, ctx就可以被拿来用了。
: 理论上这时就可以发送数据了。但是实践发现, 这时的TCP连接是准备好了,但是
TLS
: 的handshake 还没有完成。 如果这时发送数据,数据会无声无息的丢掉。这个很烦
人。
: TLS的handshake在channelRead(ChannelHandlerContext ctx, Object msg)被调用的时
: 候(即收到一个数据包时)是完成了的。 但是这个程序是客户端,它应当先发送数据给
: ...................
多谢。
你的这个是正解,跟Netty的event-driven 的设计思路相符。程序改正后表现好很多了。
【 在 fantasist (一) 的大作中提到: 】
: 需要的大概是这个:https://netty.io/4.0/api/io/netty/handler/ssl/SslHandler.
: html#handshakeFuture--
: 现在高级的语言基本都不用你自己检查状态,“HandshakeStatus.FINISHED”这种东西
: 是implementation detail,用户自己引用不仅容易出错,版本升级还会带来兼容性问
: 题。callback是王道,一般只需要自己定义onSuccess和onFailure。Modern C++都这么
: 写了,效率高很多。