如何快速从 tcp socket 接收一个数据包 java
How to receive only one packet from tcp socket quickly java
远程Tcp Server设备一次发送8个字节的数据,发送速度相对较快(但不是特别快)。无论如何,我想接收 8 个字节并在给定的 8 个字节上执行。但是,我似乎正在接收这 8 个字节的倍数的字节数组,回到我的计数(在代码中)是 8 个字节的几个倍数,长度从 16 到 120+ 字节不等。
检查 Wireshark,远程 Tcp 服务器似乎正确发送了 8 个字节,但没有合并它们。这向我表明套接字的读取速度太慢,因此对我来说将 8 个字节的间隔背靠背组合在一起,这是我不想要的。?一个例子是:
8字节-8字节-16字节-8字节-8字节-56字节。
这里是数据流多快的时间戳。只有 10 毫秒。
(13:44:23.210) 00h 10h 01h 06h FFh 3Ah FFh FFh
(13:44:23.290) 00h 10h 01h 06h FFh 3Fh FFh FFh
(13:44:23.300) 00h 10h 01h 06h FFh 44h FFh FFh
如何在确保 8 字节数据不是倍数的情况下尽可能快地有效地从端口读取数据?
下面的代码是一个片段,它读取未知大小的数据并将其发回给 NetworkManager 以供进一步处理。我曾尝试使用不同的流,希望获得预期的效果,但两种流都无法确保这一点。
private class Receive extends Thread {
private InputStream inputStream;
private DataInputStream dataInputStream;
private BufferedInputStream bufferedInputStream;
private ByteArrayOutputStream byteArrayOutputStream;
public void run() {
if (DEBUG) Log.d(TAG + " \"" + name + "\"", String.valueOf(getId()) + ":receive run.");
bundle = new Bundle();
buffer = new byte[1024];
try {
bufferedInputStream = new BufferedInputStream(socket.getInputStream());
} catch (IOException ioException) {
Log.d(TAG + " \"" + name + "\"", String.valueOf(getId()) + ":IOException", ioException);
}
while (connected && !closed) {
if (DEBUG) Log.d(TAG + " \"" + name + "\"", String.valueOf(getId()) + ":retry read.");
try {
// socket.setSoTimeout(timeout);
int count = bufferedInputStream.read(buffer);
byteArrayOutputStream = new ByteArrayOutputStream(count);
if (count == -1) {
networkManager.stopTcpNetwork(name);
closed = true;
Log.d(TAG + " \"" + name + "\"", String.valueOf(getId()) + "Connection Lost?!?!");
} else {
if (DEBUG) Log.d(TAG + " \"" + name + "\"", String.valueOf(getId()) + ":call back." + " Count: " + String.valueOf(count));
byteArrayOutputStream.write(buffer, 0, count);
bundle.putByteArray(name, byteArrayOutputStream.toByteArray());
// bundle.putByteArray(name, buffer);
message = networkManager.obtainMessage();
message.what = Messages.MESSAGES_TCP_DATA.getInt();
message.setData(bundle);
networkManager.sendMessage(message);
}
} catch (SocketTimeoutException socketTimeoutException) {
if (DEBUG) Log.d(TAG + " \"" + name + "\"", String.valueOf(getId()) + ":no data yet.");
} catch (Exception exception) {
Log.d(TAG + " \"" + name + "\"", String.valueOf(getId()) + ":Exception", exception);
}
}
}
}
我猜套接字只是在数据被读入缓冲区之前缓冲数据。正如其他人指出的那样,正确的答案是要么从套接字中读取所有内容,要么只从套接字中读取预期数量的字节。
无论如何,项目在增长,需要引入的数据也在增长。话虽这么说,最简单的方法是将数据发送回另一个线程进行本地缓冲,然后最终循环处理潜在消息(已检查是否完整)并继续处理。
所以,希望这对其他人有帮助.. 如果没有,抱歉。
感谢所有评论和帮助的人!
远程Tcp Server设备一次发送8个字节的数据,发送速度相对较快(但不是特别快)。无论如何,我想接收 8 个字节并在给定的 8 个字节上执行。但是,我似乎正在接收这 8 个字节的倍数的字节数组,回到我的计数(在代码中)是 8 个字节的几个倍数,长度从 16 到 120+ 字节不等。
检查 Wireshark,远程 Tcp 服务器似乎正确发送了 8 个字节,但没有合并它们。这向我表明套接字的读取速度太慢,因此对我来说将 8 个字节的间隔背靠背组合在一起,这是我不想要的。?一个例子是:
8字节-8字节-16字节-8字节-8字节-56字节。
这里是数据流多快的时间戳。只有 10 毫秒。
(13:44:23.210) 00h 10h 01h 06h FFh 3Ah FFh FFh
(13:44:23.290) 00h 10h 01h 06h FFh 3Fh FFh FFh
(13:44:23.300) 00h 10h 01h 06h FFh 44h FFh FFh
如何在确保 8 字节数据不是倍数的情况下尽可能快地有效地从端口读取数据?
下面的代码是一个片段,它读取未知大小的数据并将其发回给 NetworkManager 以供进一步处理。我曾尝试使用不同的流,希望获得预期的效果,但两种流都无法确保这一点。
private class Receive extends Thread {
private InputStream inputStream;
private DataInputStream dataInputStream;
private BufferedInputStream bufferedInputStream;
private ByteArrayOutputStream byteArrayOutputStream;
public void run() {
if (DEBUG) Log.d(TAG + " \"" + name + "\"", String.valueOf(getId()) + ":receive run.");
bundle = new Bundle();
buffer = new byte[1024];
try {
bufferedInputStream = new BufferedInputStream(socket.getInputStream());
} catch (IOException ioException) {
Log.d(TAG + " \"" + name + "\"", String.valueOf(getId()) + ":IOException", ioException);
}
while (connected && !closed) {
if (DEBUG) Log.d(TAG + " \"" + name + "\"", String.valueOf(getId()) + ":retry read.");
try {
// socket.setSoTimeout(timeout);
int count = bufferedInputStream.read(buffer);
byteArrayOutputStream = new ByteArrayOutputStream(count);
if (count == -1) {
networkManager.stopTcpNetwork(name);
closed = true;
Log.d(TAG + " \"" + name + "\"", String.valueOf(getId()) + "Connection Lost?!?!");
} else {
if (DEBUG) Log.d(TAG + " \"" + name + "\"", String.valueOf(getId()) + ":call back." + " Count: " + String.valueOf(count));
byteArrayOutputStream.write(buffer, 0, count);
bundle.putByteArray(name, byteArrayOutputStream.toByteArray());
// bundle.putByteArray(name, buffer);
message = networkManager.obtainMessage();
message.what = Messages.MESSAGES_TCP_DATA.getInt();
message.setData(bundle);
networkManager.sendMessage(message);
}
} catch (SocketTimeoutException socketTimeoutException) {
if (DEBUG) Log.d(TAG + " \"" + name + "\"", String.valueOf(getId()) + ":no data yet.");
} catch (Exception exception) {
Log.d(TAG + " \"" + name + "\"", String.valueOf(getId()) + ":Exception", exception);
}
}
}
}
我猜套接字只是在数据被读入缓冲区之前缓冲数据。正如其他人指出的那样,正确的答案是要么从套接字中读取所有内容,要么只从套接字中读取预期数量的字节。
无论如何,项目在增长,需要引入的数据也在增长。话虽这么说,最简单的方法是将数据发送回另一个线程进行本地缓冲,然后最终循环处理潜在消息(已检查是否完整)并继续处理。
所以,希望这对其他人有帮助.. 如果没有,抱歉。 感谢所有评论和帮助的人!