gpt4 book ai didi

java - DataInputStream readInt() 只工作一次

转载 作者:行者123 更新时间:2023-11-29 07:52:50 28 4
gpt4 key购买 nike

我正在使用 Java 套接字让两个 Android 设备与同一个应用进行通信。通信协议(protocol)为:

1. client sends packet size S
2. client sends byte array with size S

我正在使用 DataOutputStreamwriteInt() 将大小作为原始值写入流中。然后服务器通过 DataInputStreamreadInt() 读取这个值。问题是 readInt() 只为第一个数据包读取正确的值。此方法第二次返回随机 int

相关代码 fragment :

客户端:此方法在与服务器的有效 TCP 连接之上调用

public void write(byte[] packet)
{
try
{
dataOutputStream.writeInt(packet.length);
dataOutputStream.flush();

dataOutputStream.write(packet);
dataOutputStream.flush();
}
catch (IOException e)
{
Log.e(ERROR_TAG, "write() failed", e);
}
}

服务器端:这是读取数据的循环

...

int readBytes = 0;
int packetSize = 0;

while (true) {
byte[] buffer = new byte[NET_BUFF_SIZE];

try // first it reads the packet size from packet header
{
packetSize = dataInputStream.readInt();
} catch (IOException e) {
Log.e(ERROR_TAG, "readInt() failed", e);
return;
}

while (readBytes < packetSize) {
try {
int readResult = dataInputStream.read(buffer);

if (readResult != -1) {
readBytes += readResult;
} else {
break;
}
} catch (IOException e) {
Log.e(ERROR_TAG, "read() failed", e);
break;
}
}
}

因此,当客户端调用 write() 发送第二个数据包时,服务器从流中读取了错误的大小。

DataOutputStreamDataInputStream 是这样初始化的:

// Server
inputStream = clientSocket.getInputStream();
dataInputStream = new DataInputStream(inputStream);

// Client
outputStream = socket.getOutputStream();
dataOutputStream = new DataOutputStream(outputStream);

我错过了什么?

最佳答案

服务器读取尽可能多的可用数据。它可能会读取比客户端发送的数据包中包含的内容更多的内容,也可能会读取更少的内容。使用循环,您似乎可以处理 read 返回的结果少于预期的情况,但您也应该处理读取的内容多于数据包中包含的内容的情况。请记住,TCP 是面向流的:即使您调用 flush,也不能保证远程应用程序在单独调用 read 时接收到数据。

DataInput 接口(interface)定义了一个名为 readFully 的方法,它可以根据需要读取任意数量的字节,不多也不少。这意味着您可以删除循环,简化读取数据包的代码:

packetSize = dataInputStream.readInt();
dataInputStream.readFully(buffer, 0, packetSize);

关于java - DataInputStream readInt() 只工作一次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19859375/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com