使用TCP连接获取字节数组



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

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

我们如何从DataInputStream中获取字节[],类似于以下内容:

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

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

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;
}

答案由两部分组成。处理与您的问题相关的两个单独的问题。

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个字节。您将如何实际做到这一点通常与您的实际用例密切相关。这取决于您的

相关内容

  • 没有找到相关文章

最新更新