public void client() throws IOException {
//创建套接字通道
SocketChannel sChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1", 9898));
//文件通道,连接文件
FileChannel inChannel = FileChannel.open(Paths.get("1.txt"), StandardOpenOption.READ);
//创建一个1024字节大小的缓存
ByteBuffer buf = ByteBuffer.allocate(1024);
//将字节序列从此通道中读入给定的缓冲区,如果通道中的数据读完了就终止循环
while(inChannel.read(buf) != -1){
//把缓冲当前位置指针移动到初始0位置
buf.flip();
//将字节序列从给定的缓冲区中写入此通道。
sChannel.write(buf);
//清空缓存
buf.clear();
}
//为什么要使用shutdownOutput呢,如果用close,name整个通道都会关闭,包括网络连接,所以肯定不行,因为接下去还有其他操作
//而wirte还没有关闭通道一直处于写入状态,服务端sChannel并不知道结束了,所以还一直等待客户端的输出(阻塞)
sChannel.shutdownOutput();
//接收服务端的反馈
int len = 0;
while((len = sChannel.read(buf)) != -1){
buf.flip();
System.out.println(new String(buf.array(), 0, len));
buf.clear();
}
inChannel.close();
sChannel.close();
}
public void server() throws IOException {
ServerSocketChannel ssChannel = ServerSocketChannel.open();
FileChannel outChannel = FileChannel.open(Paths.get("2.txt"), StandardOpenOption.WRITE, StandardOpenOption.CREATE);
ssChannel.bind(new InetSocketAddress(9898));
//一直等到有客户端链接,会一直阻塞
SocketChannel sChannel = ssChannel.accept();
ByteBuffer buf = ByteBuffer.allocate(1024);
//客户端若是没加sChannel.shutdownOutput();,服务端会以为客户端还在发送数据过来,所以一直等待,死循环
//而加了sChannel.shutdownOutput(),标记输出流为-1,相当于达到末尾,这时候服务端清楚你已经不再发数据了,就会终止循环,到下一步
//read(buf)读取的字节数,可能为零,如果该通道已到达流的末尾,则返回 -1
while(sChannel.read(buf) != -1){
System.out.println(111);
buf.flip();
outChannel.write(buf);
buf.clear();
}
//发送反馈给客户端
buf.put("服务端接收数据成功".getBytes());
buf.flip();
sChannel.write(buf);
sChannel.close();
outChannel.close();
ssChannel.close();
}
同时启动这俩程序
主要是客户端加这个sChannel.shutdownOutput(),不然去掉这个会死循环,服务端会一直等客户端发送数据过来,会死掉