首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java AsynchronousSocketChannel读操作

Java AsynchronousSocketChannel读操作
EN

Stack Overflow用户
提问于 2015-05-21 05:23:16
回答 1查看 325关注 0票数 0

我在我的项目中使用了来自nio2的java AsynchronousSocketChannel。我也在ubuntu14.04上使用oracle jdk 1.7.0_80。

我的项目是一个处理二进制数据的服务器。代码在CompletionHandler匿名类的completed方法中递归调用读取操作,如下所示:

代码语言:javascript
复制
private final CompletionHandler<Integer,AsynchronousSocketChannel> readHandler=new CompletionHandler<Integer,AsynchronousSocketChannel>(){

    @Override
    public void completed(Integer result,AsynchronousSocketChannel attachment) {
        if(result<0){
            attachment.close();
            return;
        }
        attachment.read(swap, attachment, this);
    }
}

其中,变量swap是一个ByteBuffer实例。

显然,一切都运行得很好。但是,有一个数据包的总大小是3832字节,当服务器接收到这个完整的数据包时,没有分段,没有任何问题。但是,有时此数据包被分成两个或多个部分(TCP数据段)。第一段的大小是2896字节,第二段的大小是936字节。

最后一段没有报头,这破坏了我的算法。我想知道,有没有办法只在读完整个包之后才调用"completed“方法?

我已经将SO_RCVBUF调高到64K,但它不起作用。

EN

回答 1

Stack Overflow用户

发布于 2015-05-21 05:27:43

我想知道,有没有办法在读完整个包后才调用

方法?

不,没有办法做到这一点。

TCP协议可以将字节流分解为任意大小的数据包。您在TCP之上使用的应用层协议不能依赖于消息始终完全在一个TCP数据包中发送。

您必须以这样的方式设计应用程序级协议:它可以处理以任意大小的数据包分解的消息。

一种常见的方法是在应用程序级消息前面加上一个长度字段。例如,应用程序级消息由4个字节的字段组成,其中包含消息的其余部分的长度。当您接收消息时,您首先接收长度,然后您应该继续接收,直到您接收到那么多字节,然后您可以将这些字节组装成应用程序级消息。

AsynchronousSocketChannel应用程序接口不能自动为您重新组装应用程序级别的消息,因为它不了解您的应用程序级别协议的任何信息。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30360640

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档