gpt4 book ai didi

java - 如何使用socket channel 发送文件名和文件内容

转载 作者:太空宇宙 更新时间:2023-11-04 13:40:04 25 4
gpt4 key购买 nike

我想使用套接字 channel 一起发送文件名和文件内容。我尝试将文件名转换为字节,将这些字节包装在字节缓冲区中,然后将这些缓冲区内容发送到客户端(这是在服务器端)。

在客户端,我尝试循环遍历缓冲区中的内容,将字节转换为字符,并检查是否存在特殊字符以记录文件名的结尾。当识别到该字符时,我调用缓冲区方法compact(),以便我现在可以开始读取内容。但这不起作用!我的客户端第一个 while 循环 while(bb.hasRemaining()) 没有中断,并且该循环中没有打印任何字符!!

服务器端

FileChannel sbc;
ServerSocketChannel ssc=null;
SocketChannel clientchannel=null;

try {

ssc=ServerSocketChannel.open();
ssc.bind(new InetSocketAddress(5002));

clientchannel=ssc.accept();

String filename=f.getName()+"?";
byte[] nameinbytes=filename.getBytes("UTF-8");
System.out.println("name of file to send: "+filename);
ByteBuffer namebuffer=ByteBuffer.wrap(nameinbytes);
clientchannel.write(namebuffer);

sbc=FileChannel.open(f.toPath());
ByteBuffer buff=ByteBuffer.allocate(10000000);

int bytesread=sbc.read(buff);
double read=(double)bytesread;
while(bytesread != -1){
read+=(double) bytesread;
buff.flip();
clientchannel.write(buff);
buff.clear();
System.out.println("current position: "+sbc.position());
bytesread=sbc.read(buff);
}
System.out.println("file data written");

客户端

SocketAddress address=new InetSocketAddress(InetAddress.getLocalHost(),5002);
clientChannel=SocketChannel.open(address);
ByteBuffer bb=ByteBuffer.allocate(10000000);
int bytesRead=clientChannel.read(bb);
String filename="";
while(bb.hasRemaining()){
byte bm=bb.get();
char c=(char)(bm & 0xFF);
System.out.println(c);
if(c != '?'){
filename+=Character.toString(c);
}else{
bb.compact();
break;
}
}

File file=new File("C:\\Users\\C-I-C\\Desktop\\fromclient\\"+filename);

bout =new FileOutputStream(file);
sbc=bout.getChannel();

while(bytesRead != -1){
bb.flip();
sbc.write(bb);
bb.clear();
bytesRead=clientChannel.read(bb);
}
System.out.println("received: "+filename);

如何使用同一 channel 发送文件名和文件内容?

最佳答案

服务器端

  1. 将文件名转换为字节数组。
  2. 将字节数组包装在 ByteBuffer 对象中。
  3. 将 ByteBuffer 对象内容发送到套接字 channel

发送包含文件名的缓冲区后(当然以字节为单位):

  • 现在创建另一个 ByteBuffer 对象并为其指定大小
  • 开始将文件内容从 FileChannel 对象读取到缓冲区。
  • 在 while 循环中,开始将内容发送到套接字 channel ,直到到达文件 channel 的文件末尾。

    ServerSocket server=ServerSocket.open();
    server.bind(new InetSocketAddress(1000));
    SocketChannel clientChannel= server.accept();
    File fileToSend=new File("stalkunderflow.txt").
    String filename=fileToSend.getName();
    byte[] nameBytes=filename.getBytes("UTF-8");
    ByteBuffer nameBuffer=ByteBuffer.wrap(nameBytes);
    clientChannel.write(nameBuffer);

    //now prepare and send file contents

    FileChannel sbc=FileChannel.open(fileToSend.toPath());
    ByteBuffer buff=ByteBuffer.allocate(10000000);

    int bytesread=sbc.read(buff);

    while(bytesread != -1){
    buff.flip();
    clientChannel.write(buff);
    buff.compact();
    bytesread=sbc.read(buff);
    }
  • 客户端

    1. 创建一个 ByteBuffer 对象(可以称之为 nameBuffer)并给它一个大小(不是很大)。

    2. 将套接字 channel 的内容写入缓冲区。

    3. 翻转缓冲区并开始将缓冲区内容写入字节数组。(在 while 循环中执行)

    4. 将字节数组转换为字符串,即可得到文件名。

    5. 之后,创建另一个 ByteBuffer 对象(称为 nameBuffer)来存储文件内容,现在您将从该 nameBuffer 读取到文件 channel ,该文件 channel 使用从 nameBuffer 获得的名称写入文件。

       //this is a test enviroment,therefore my server is running on the same machine as the client. 
      SocketAddress address=new InetSocketAddress(InetAddress.getLocalHost(),1000);
      SocketChannel clientChannel=SocketChannel.open(address);

      ByteBuffer namebuff=ByteBuffer.allocate(500);
      clientChannel.read(namebuff);

      byte[] namebyte=new byte[500];
      String filename="";

      int position=namebuff.position();

      while(namebuff.hasRemaining()){
      namebyte[position]=namebuff.get();
      position=namebuff.position();
      }
      filename=new String(namebyte,0,position);

      File file=new File(filename);

      ByteBuffer bb=ByteBuffer.allocate(10000000);
      int bytesRead=clientChannel.read(bb);
      FileOutputStream bout =new FileOutputStream(file);
      FileChannel sbc=bout.getChannel();

      while(bytesRead != -1){
      bb.flip();
      sbc.write(bb);
      bb.compact();
      bytesRead=clientChannel.read(bb);
      }

    关于java - 如何使用socket channel 发送文件名和文件内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31313987/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com