首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Java套接字问题:数据包在接收端合并

Java套接字问题:数据包在接收端合并
EN

Stack Overflow用户
提问于 2011-10-15 00:04:22
回答 3查看 1K关注 0票数 1

我有一个插座问题。当我在同一台PC上运行服务器和客户端时,也就是使用"localhost“参数时,就会出现这个问题。但当使用不同的PC时,不会出现问题。客户端发送包含以下代码的文件:

代码语言:javascript
运行
复制
output_local.write(buffer, 0, bytesRead);
output_local.flush();

在此之后,在另一种方法中,我将使用以下命令发送命令:

代码语言:javascript
运行
复制
outputStream.write(string);
outputStream.flush();

服务器将命令附加到文件的末尾。所以它认为它还没有收到来自客户端的命令。你知道是什么原因导致这个问题吗?我如何解决这个缺陷?以下是服务器端的文件接收方式:

代码语言:javascript
运行
复制
    while (true) {
        try {
            bytesReceived = input.read(buffer);
        } catch (IOException ex) {
            Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
            System.out.println("exception occured");
            break;
        }
        System.out.println("received:" + bytesReceived);
        try {
            /* Write to the file */
            wr.write(buffer, 0, bytesReceived);
        } catch (IOException ex) {
            Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
        }
        total_byte = total_byte + bytesReceived;
        if (total_byte >= filesizeInt) {
            break;
        }
    }
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-10-15 00:09:16

如果你想要类似消息的支持,你需要创建一个协议来阐明你要发送和接收的内容。

在TCP中,您不能依赖于单独接收单独的“数据包”(例如,发送4个10字节的数据块可能被接收为40个数据块中的1个数据块,或者20个数据块中的2个数据块,或者39个数据块中的一个数据块和1个数据块中的一个数据块)。TCP保证顺序传送,但不保证数据的任何特定“打包”。

所以,举个例子,如果你要发送一个字符串,你需要先发送字符串的长度,然后发送它的字节。伪代码中的逻辑应该是这样的:

客户端:

  1. 发送命令指示符
  2. 发送有效负载长度
  3. 发送有效负载

服务器:

  • 读取命令indicator

  • Read payload length
  1. 循环读取有效负载,直到完整长度已读取
票数 7
EN

Stack Overflow用户

发布于 2011-10-15 00:09:44

缺点是您将基于流的协议(TCP)视为面向消息的协议。事实并非如此。你应该假设这是可能发生的。

如果需要将流拆分为多个单独的消息,则应该对每个消息使用分隔符或长度前缀(最好是IMO)。然后,您还应该预料到,您发出的任何读取可能不会收到您所请求的那么多数据-换句话说,如果您不小心,不仅消息可能被合并,而且它们很容易被拆分。

我提到我更喜欢长度前缀而不是分隔符。利弊:

  • 使用消息分隔符的好处是,在开始发送之前不需要知道消息的大小。
  • 使用长度前缀的好处是:
    • 读取消息的代码根本不需要关心消息中的数据-它只需要知道它有多长。您读取消息长度,读取消息数据(循环,直到您读完所有内容),然后将消息传递给process。如果你想让分隔符出现在一个普通的message.

中,你不需要担心“转义”

票数 5
EN

Stack Overflow用户

发布于 2011-10-15 00:08:52

由于TCP是面向流的连接,如果写入器的写入速度快于读取器的读取速度,或者TCP堆栈发送数据包的速度快,则这种行为是正常的。

您应该添加分隔符来分隔流的各个部分,例如,对子数据包使用长度字段,或者使用诸如换行符(\n,字符代码10)之类的分隔符。

另一种选择是使用UDP (甚至SCTP),但这取决于要完成的任务。

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

https://stackoverflow.com/questions/7770382

复制
相关文章

相似问题

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