gpt4 book ai didi

Java SocketChannel 吃掉我的字节

转载 作者:太空宇宙 更新时间:2023-11-04 08:57:50 25 4
gpt4 key购买 nike

我创建了一个到远程服务器的 SocketChannel,以便在 Tomcat 上发送和接收消息。为了从远程计算机接收消息,我使用了一个专用于任务的线程(只有这个线程将从套接字读取,没有其他线程)。

当 SocketChannel 接收到一些字节时(我不断在非阻塞模式下轮询 SocketChannel 以获取新数据),我首先读取 4 个字节以获取下一条消息的长度,然后从 SocketChannel 分配并读取 x 个字节,然后将其解码并重构为消息。

下面是我的接收线程代码:

@Override
public void run() {

while (true) { //Don't exit thread

//Attempt to read the size of the incoming message
ByteBuffer buf = ByteBuffer.allocate(4);

int bytesread = 0;
try {
while (buf.remaining() > 0) {
bytesread = schannel.read(buf);

if (bytesread == -1) { //Socket was terminated

}

if (quitthread) break;
}

} catch (IOException ex) {

}

if (buf.remaining() == 0) {
//Read the header
byte[] header = buf.array();
int msgsize = (0xFF & (int)header[0]) + ((0xFF & (int)header[1]) << 8)
+ ((0xFF & (int)header[2]) << 16) + ((0xFF & (int)header[3]) << 24);

//Read the message coming from the pipeline
buf = ByteBuffer.allocate(msgsize);
try {
while (buf.remaining() > 0) {
bytesread = schannel.read(buf);

if (bytesread == -1) { //Socket was terminated

}

if (quitthread) break;
}
} catch (IOException ex) {

}

parent.recvMessage(buf.array());
}

if (quitthread) {
break;
}
}

}

我从 SocketChannel 收到的第一个字节很好,并且我成功解码了消息。然而,下次我从 SocketChannel 读取时,套接字向前跳过了大约 100 个字节,这导致读取错误的字节并将其解释为长度,从而导致所有内容都损坏。

代码有什么问题吗?没有其他线程正在从 SocketChannel 读取数据。

最佳答案

你的括号被去掉,代码是:

(0xFF & ((int)header[1] << 8))

始终为 0(与 << 16 和 << 24 相同),我猜你的意思是:

((0xFF & ((int)header[1])) << 8)

这会导致读取的消息字节不足,还会导致同步不匹配(而不是读取太多消息字节。)

编辑:现在您已修复上述问题,我看不出有什么问题。你能告诉我们第一条消息的长度和被吃掉的确切字节数之间的关系吗?

根据显示的代码,我唯一的猜测是您从显示的示例中编辑了一些可能影响 schannel 的行为,schannel 是否在其他地方引用?

如果行:

ByteBuffer buf = ByteBuffer.allocate(4);

将位于 while 之外,这会导致您所描述的行为,但在示例代码中并非如此。

关于Java SocketChannel 吃掉我的字节,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1743124/

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