我正在尝试使用服务器类中的 ServerSocketChannel 和客户端类中的 SocketChannel 将文件从服务器发送到客户端。两个类对象都处于阻塞模式。
文件已发送得很好但无法以编程方式确定文件已到达!我必须转到已在客户端类中保存已发送文件的文件夹,以检查其大小,并将其大小与服务器类中的原始文件进行比较。这是因为System.out.println("received: "+filename);
语句永远不会在我的客户端类中执行。但是执行服务器类中的System.out.println("file data sent");
。
服务器类代码
ServerSocketChannel ssc=ServerSocketChannel.open();
ssc.bind(new InetSocketAddress(5002));
SocketChannel clientchannel=ssc.accept();
FileChannel sbc=FileChannel.open(f.toPath());
ByteBuffer buff=ByteBuffer.allocate(10000000);
int size=(int)sbc.size();
int read=1000000;
System.out.println("file size: "+size);
int bytesread=sbc.read(buff);
while(bytesread != -1){
buff.flip();
clientchannel.write(buff);
buff.clear();
System.out.println("current position: "+sbc.position());
bytesread=sbc.read(buff);
}
System.out.println("file data sent");
客户端类代码
clientChannel=SocketChannel.open(address);
ByteBuffer bb=ByteBuffer.allocate(10000000);
int bytesRead=clientChannel.read(bb);
FileOutputStream bout =new FileOutputStream(file);
FileChannel sbc=bout.getChannel();
while(bytesRead !=-1){
System.out.println(" bytes read :"+bytesRead);
bb.flip();
sbc.write(bb);
bb.clear();
bytesRead=clientChannel.read(bb);
}
System.out.println("received: "+filename);
问题
我的代码中缺少什么使得最后一个语句System.out.println("received: "+filename);
不被执行。就像我的客户端程序在收到所有字节后陷入死锁一样!
答案 0 :(得分:0)
您可以在发送文件后关闭服务器类中的频道,以便频道上的任何进一步读取都将返回-1
,即流末尾指示..
ServerSocketChannel ssc=ServerSocketChannel.open();
ssc.bind(new InetSocketAddress(5002));
SocketChannel clientchannel;
try{
clientchannel=ssc.accept();
FileChannel sbc=FileChannel.open(f.toPath());
ByteBuffer buff=ByteBuffer.allocate(10000000);
int size=(int)sbc.size();
int read=1000000;
System.out.println("file size: "+size);
int bytesread=sbc.read(buff);
while(bytesread != -1){
buff.flip();
clientchannel.write(buff);
buff.clear();
System.out.println("current position: "+sbc.position());
bytesread=sbc.read(buff);
}
System.out.println("file data sent");
}catch(IOException ioe){
ioe.printStackTrace();
}finally{
if(clientchannel !=null){
try {
clientchannel.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}