【发布时间】:2019-12-11 16:05:36
【问题描述】:
我正在开展一个项目,以更好地了解 Java NIO 和网络编程内容。我正在尝试通过 netcat 将 400,000+ 字节的文件发送到我的服务器,在那里可以找到它并将其写入文件。
问题: 当文件小于 10,000 字节时,或者当我在 Select() 之前放置一个 Thread.sleep(timeout) 时,该程序可以完美运行。文件发送过来但只读取 8192 字节,然后取消循环并返回到 select() 以捕获其余数据。但是,该文件捕获了之后的内容。我需要完整的数据以进一步扩展项目。
我尝试过的事情: 我试图将数据加载到另一个显然有效的字节数组中,但跳过了 8192 个字节(因为再次调用了 select())。读取剩余的 391000 个字节。比较文件时,缺少前 8192 个字节。 我尝试了其他各种方法,但我在 NIO 中还不足以理解我在搞砸什么。
我的代码
这就是我觉得代码混乱的地方(调试后)
private void startServer() {
File temp = new File("Filepath");
Selector selector = Selector.open();
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.configureBlocking(false);
serverSocketChannel.socket().bind(listenAddress);
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
log.info("Server Socket Channel Started");
while(!stopRequested){
selector.select();
Set<SelectionKey> keys = selector.selectedKeys();
for(SelectionKey key : keys){
if(key.isAcceptable()){
try {
serverSocketChannel = (ServerSocketChannel) key.channel();
SocketChannel socket = serverSocketChannel.accept();
socket.configureBlocking(false);
socket.register(selector, SelectionKey.OP_READ);
}catch (IOException e) {
log.error("IOException caught: ", e);
}
}
if(key.isReadable(){ read(key); }
keys.remove(key);
}
}
} catch (IOException e) {
log.error("Error: ", e);
}
}
private void read(SelectionKey key) {
int count = 0;
File tmp = new File("Path");
try {
SocketChannel channel = (SocketChannel) key.channel();
byteBuffer.clear();
while((count = channel.read(byteBuffer)) > 0) {
byteBuffer.flip();
//in bytearrayoutputstream to append to data byte array
byteArrayOutputStream.write(byteBuffer.array(), byteBuffer.arrayOffset(), count);
byteBuffer.compact();
}
}
data = byteArrayOutputStream.toByteArray();
FileUtils.writeByteArrayToFile(tmp, data);
}
}
上面的代码是我正在使用的。我在这门课上有更多的东西,但我相信有问题的主要两个功能是这两个。我不太确定我应该采取什么步骤。我必须测试我的程序的文件包含许多大约 400,000 字节的 TCP。 select() 收集最初的 8192 个字节,然后运行读取(在捕获流中的所有数据之前不应发生这种情况),然后返回并收集其余部分。我已将 byteBuffer 分配为 30720 字节。
如果不清楚,我可以发布其余代码,让我知道您的建议。
问题
为什么分配空间为 30720 时,这段代码只抓取 8192 字节?为什么它在调试模式下或与 Thread.sleep() 一起工作?
以前的人建议我将 byteBuffer.clear() 放在循环之外,即使这样做了,问题仍然存在。
【问题讨论】:
标签: java networking selector nio