- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我在使用 NIO 框架通过 SocketChannel 在主机和客户端之间发送数据时遇到问题。
我以前从来没有真正费心去学习 NIO,但是随着 java.nio.files 包的引入和其他各种改进,我想我应该尝试一下。
我能够使 SocketChannel 和 ServerSocketChannel 正常连接,但实际的数据传输表现得很奇怪。它永远不会在客户端正确完成,总是在最终读取后挂起。此外,它有时会读取不正确的数据量(太多或太少),甚至导致 Windows 资源管理器变得疯狂并分配几乎所有系统内存,从而导致计算机崩溃。
这是我现在拥有的代码(它是测试代码):
package bg.jdk7.io;
import static java.nio.file.StandardOpenOption.*;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
public class NetIO {
static volatile long filesize;
public static void main(String[] args) {
new Thread(new Client()).start();
try {
ServerSocketChannel ssc = ServerSocketChannel.open();
ssc.bind(new InetSocketAddress(5555));
SocketChannel sc = ssc.accept();
if(sc.isConnected()) {
ByteBuffer buff = ByteBuffer.allocate(10240);
Path fp = Paths.get(System.getProperty("user.home")+"\\Documents\\clip0025.avi");
if(Files.exists(fp)) {
FileChannel fc = (FileChannel) Files.newByteChannel(fp, StandardOpenOption.READ);
long tot = Files.size(fp);
long run = 0;
int read = 0;
int prog = 0;
while((read = fc.read(buff))>0) {
buff.rewind();
sc.write(buff);
run+=buff.position();
int last = prog;
prog = (int)(((double)run/tot)*100);
if(prog !=last) {
System.out.println(prog + "%");
}
buff.flip();
}
fc.close();
System.out.println("Sending completed");
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
<小时/>
static class Client implements Runnable {
public void run() {
try {
SocketChannel sc = SocketChannel.open();
sc.connect(new InetSocketAddress("localhost",5555));
if(sc.isConnected()) {
Path dpf = Paths.get("\\NIO_TESTING\\");
Path dp = Paths.get(dpf+"\\clip.avi");
Files.createDirectories(dpf);
FileChannel fc = (FileChannel) Files.newByteChannel(dp, CREATE, WRITE, TRUNCATE_EXISTING);
ByteBuffer buff = ByteBuffer.allocate(10240);
int read;
int total = 0;
while((read = sc.read(buff))>0) {
total+=read;
buff.rewind();
fc.write(buff);
System.out.println(fc.size());
buff.flip();
if(total == filesize) System.out.println("File data received successfully...");
}
System.out.println("Completed successfully");
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
最佳答案
由 ServerSocketChannel.accept()
生成的 SocketChannel
已连接。不可能是这样。 isConnected()
测试毫无意义。
您的服务器 I/O 代码不正确。 channel 写入必须在 buffer.flip()
之前,然后是 buffer.compact()。
从一个 channel 复制到另一个 channel 的规范方法如下(请注意,即使缓冲区中仍有待处理的数据,这在 EOS 上也能正确运行):
while (in.read(buffer) >= 0 || buffer.position() > 0)
{
buffer.flip();
out.write(buffer);
buffer.compact();
}
与我的第一段类似,由 SocketChannel.open()
后跟 SocketChannel.connect()
产生的 SocketChannel
是 连接:再次强调,测试毫无意义。如果未连接,connect()
调用上就会出现 ConnectException
。
您的客户端 I/O 代码与服务器 I/O 代码存在相同的问题。
您没有关闭服务器中的SocketChannel
,因此客户端永远不会停止从连接中读取数据。
您也没有关闭客户端中的SocketChannel
。
File.exists()
测试毫无意义。如果文件不存在,下面的行将引发异常,并且您无论如何都必须处理该异常,那么为什么还要再次执行呢?
关于java - 蔚来挂机问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8115290/
我是一名优秀的程序员,十分优秀!