我使用UDP
发送/接收数据,但我现在想切换到TCP
,以避免数据包丢失。
我读过几个教程TCP
和发现,而不是使用像DatagramPacket类UDP
, TCP
使用的InputStream / OutputStream中。
我们如何从DataInputStream类的字节[],东西是与此类似:
byte[] receiveData = new byte[64000];
DatagramPacket receivePacket = new DatagramPacket(receiveData,receiveData.length);
receiveData=receivePacket.getData();
答案有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个字节。 您将如何真正做到这一点通常是密切相关的实际使用情况。 它是由你
为了实现通过套接字(流)基于消息的协议,你基本上要拿出一些消息格式,然后读/写在连接的两端。 一个非常简单的格式是写该消息的长度为4字节整型,然后发送消息字节(然后冲洗流)。 在接收端,读一个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;
}