我有服务器和客户端。 服务器使用以下方式发送数据:
private int writeMessage(AgentHandler agentHandler, Msg message) {
SocketChannel sc = agentHandler.getSocketChannel();
byte[] encodedMessage = Encoder.INSTANCE.encode(message);
ByteBuffer writeBuffer = ByteBuffer.wrap(encodedMessage);
int count = 0;
while (writeBuffer.hasRemaining()) {
try {
int written = sc.write(writeBuffer);
count += written;
} catch (IOException e) {
deregisterAgent(agentHandler.getAgentID());
}
}
System.out.printf("Written bytes: %s\n", count);
return count;
}
我有输出:
书面字节:31904
客户端使用下一段代码接收数据:
private void readFromSockets() {
int readReady = 0;
try {
readReady = readSelector.select();
} catch (IOException e) {
e.printStackTrace();
}
if (readReady > 0) {
Set<SelectionKey> selectedKeys = readSelector.selectedKeys();
Iterator<SelectionKey> keyIterator = selectedKeys.iterator();
while (keyIterator.hasNext()) {
SelectionKey key = keyIterator.next();
if (key.isReadable())
readFromSocket(key);
keyIterator.remove();
}
selectedKeys.clear();
}
}
private void readFromSocket(SelectionKey key) {
ByteBuffer byteBuffer = ByteBuffer.allocate(1024 * 1024);
SocketChannel socketChannel = (SocketChannel) key.channel();
int counter = 0, bytesRead;
try {
while ((bytesRead = socketChannel.read(byteBuffer)) != 0) {
if (bytesRead == -1) {
System.out.println("Socket channel seems disconnected.");
try {
socketChannel.close();
return;
} catch (IOException e) {
e.printStackTrace();
return;
}
}
counter += bytesRead;
System.out.println("reading from socket...");
}
} catch (IOException e) {
System.out.println("Socket Channel IO exception catched");
try {
socketChannel.close();
return;
} catch (IOException e1) {
e1.printStackTrace();
return;
}
}
System.out.println("Bytes received " + counter);
byteBuffer.flip();
byte[] message = new byte[counter];
byteBuffer.get(message, 0, counter);
Msg incomingMessage = Encoder.INSTANCE.decode(message);
if (incomingMessage != null) {
processMessage(incomingMessage);
}
}
和客户端输出
字节收到14828
此问题只能在真正远程连接的情况下表示(在我的情况下,在其他国家/地区的服务器和客户端)。
当我在localhost上测试我的代码时,我没有问题。
我需要建议如何解决这个问题。
答案 0 :(得分:0)
听起来你在数据流中遇到了暂时的缺口。如果你只是继续阅读,你最终会得到所有的消息字节。不幸的是,根据您当前的设置,您无法确定何时到达消息的末尾,是否还有更多字节,或者您是否已收到下一条消息的一部分!
通过套接字写出消息中的字节数,然后是消息本身。读取时,读取消息长度,然后读取消息字节,直到读取完整的消息。