【问题标题】:Getting byte arrays using TCP connections使用 TCP 连接获取字节数组
【发布时间】:2012-07-20 05:53:26
【问题描述】:

我之前使用UDP 发送/接收数据,但我现在想切换到TCP 以避免数据包丢失。

我已经阅读了几个关于TCP 的教程,并注意到TCP 使用InputStream/OutputStream 而不是像UDP 那样使用DatagramPacket。

我们如何从 DataInputStream 中获取 byte[],类似这样的东西:

byte[] receiveData = new byte[64000];
DatagramPacket receivePacket = new DatagramPacket(receiveData,receiveData.length); 
receiveData=receivePacket.getData();

【问题讨论】:

  • 你在使用 Java 吗?
  • 是的,我是。忘记提了。现在正在编辑帖子...
  • 您是在“流式传输”数据还是发送单个消息?

标签: java tcp udp datainputstream


【解决方案1】:

为了通过套接字(流)实现基于消息的协议,您基本上想提出一些消息格式,然后在连接的任一端读/写。一种非常简单的格式是将消息的长度写为 4 字节 int,然后发送消息字节(然后刷新流)。在接收端,读取一个 4 字节的 int,然后读取 后面的字节数(注意限制读取方法调用,否则可能会意外读取下一条消息的一部分)。

public void writeMessage(DataOutputStream dout, byte[] msg, int msgLen) {
  dout.writeInt(msgLen);
  dout.write(msg, 0, msgLen);
  dout.flush();
}

public byte[] readMessage(DataInputStream din) {
  int msgLen = din.readInt();
  byte[] msg = new byte[msgLen];
  din.readFully(msg);
  return msg;
}

【讨论】:

    【解决方案2】:

    答案分为两部分。处理与您的问题相关的 2 个独立问题。

    1。网络事实

    TCP 本质上是基于流的。即先发送字节[1000],然后发送字节[1200],与发送字节[2200]一次没有区别。实际通过网络发送的很可能是 2 个数据包,第一个是 1400 字节的数据包,第二个是 800,或 1401 和 799,并且每次都可能不同。接收方无法知道发送方实际上先发送了 1000 个字节,然后发送了 1200 个字节。这是网络设计的。 Java 与这个事实无关。而且你不能用它做任何事情。

    2。 Java实现

    在发送方。首先,您需要OutputStream os = tcpsocket.getOutputStream();。然后,每次都需要os.write(byteArray)。在接收方,您需要InputStream is = tcpsocket.getInputStream();。然后,每次都需要is.read(byteArray)。请注意,在接收方,将返回实际填充了多少byteArray。它可以是介于 1 和byteArray 容量之间的任意数字,与发送者实际发送它的方式无关。

    为了减轻任务,您可以在开头使用DataInputStream is = new DataInputStream(tcpsocket.getInputStream());,每次需要阅读时使用is.readFully(byteArray)。这样就可以保证byteArray总是被填满。

    但是如果实际长度是可变的,除非您添加一些额外的信息,否则您永远无法知道应该接收多少字节。例如,先发送长度,使用 4 个字节。您将如何实际执行此操作通常与您的实际用例密切相关。这取决于你

    【讨论】:

    • 感谢您的详尽回答。对此,我真的非常感激! :)
    • @DaoLam 我很高兴你喜欢它。
    • 你如何初始化你的字节数组,因为你还不知道它的大小?我将其大小初始化为 64000,但这导致我在代码中的其他地方出现 arrayindexoutofbounds 问题。
    • @DaoLam 这是真的。这就是我写最后一段的原因。如果你能详细说明你需要做什么,我可能会给你一个关于如何让它工作的建议。
    • 收到的字节数是否应该总是小于或等于发送的实际长度?我尝试执行以下操作来获取接收到的数组的大小:int x = is.read(byteArray);System.out.println(x); 但 x 实际上大于发送的 byteArray 的大小。这应该发生还是我做错了什么?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-22
    • 1970-01-01
    • 2018-03-05
    • 2012-09-18
    • 1970-01-01
    相关资源
    最近更新 更多