Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何使用套接字通道发送文件名和文件内容_Java_Sockets_Network Programming_Nio_Serversocket - Fatal编程技术网

Java 如何使用套接字通道发送文件名和文件内容

Java 如何使用套接字通道发送文件名和文件内容,java,sockets,network-programming,nio,serversocket,Java,Sockets,Network Programming,Nio,Serversocket,我想使用socketchannel将文件名和文件内容一起发送。 我尝试将文件名转换为字节,将这些字节包装在bytebuffer中,然后将这些缓冲区内容发送到客户端(这是在服务器端) 在客户端,我尝试循环浏览缓冲区中的内容,将字节转换为字符,并检查是否存在特殊字符以记录文件名的结尾。当识别出该字符时,我调用buffer方法compact(),这样我现在就可以开始读取内容了。但这不管用!我的客户端第一个while循环while(bb.haslaining())没有中断,并且没有从该循环打印字符 服务

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

在客户端,我尝试循环浏览缓冲区中的内容,将字节转换为字符,并检查是否存在特殊字符以记录文件名的结尾。当识别出该字符时,我调用buffer方法
compact()
,这样我现在就可以开始读取内容了。但这不管用!我的客户端第一个while循环
while(bb.haslaining())
没有中断,并且没有从该循环打印字符


服务器端

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);
客户端

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);
Q


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

服务器端

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);
  • 将文件名转换为字节数组
  • 将字节数组包装在ByteBuffer对象中
  • 将ByteBuffer对象内容发送到套接字通道
  • 发送包含文件名(当然是字节)的缓冲区后:

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

    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);
                 }
    
  • 客户端

    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);
    
  • 创建一个ByteBuffer对象(可以称之为nameBuffer)并给它一个大小(不是大的)

  • 将内容从套接字通道写入缓冲区

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

  • 将字节数组转换为字符串,就有了文件名

  • 之后,创建另一个ByteBuffer对象(称之为nameBuffer)来存储文件内容,现在您将从该nameBuffer读取到一个文件通道,该通道使用从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);
     }
    

  • 服务器端

    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);
    
  • 将文件名转换为字节数组
  • 将字节数组包装在ByteBuffer对象中
  • 将ByteBuffer对象内容发送到套接字通道
  • 发送包含文件名(当然是字节)的缓冲区后:

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

    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);
                 }
    
  • 客户端

    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);
    
  • 创建一个ByteBuffer对象(可以称之为nameBuffer)并给它一个大小(不是大的)

  • 将内容从套接字通道写入缓冲区

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

  • 将字节数组转换为字符串,就有了文件名

  • 之后,创建另一个ByteBuffer对象(称之为nameBuffer)来存储文件内容,现在您将从该nameBuffer读取到一个文件通道,该通道使用从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);
     }
    

  • 最好的方法是在服务器和客户端之间定义某种协议。你可以去看看。@CristiFati我以前也这么做过。在我的例子中,我创建了一个
    DataOutputStream来发送文件名和文件大小,然后创建了一个socketchanel
    来发送内容。此方法需要两个端口。我在想有一种方法可以在整个过程中只使用一个端口。为什么发送两个内容需要两个端口?使用相同的连接(和通道),需要交替执行读/写操作。@CristiFati我们只编写一个通道。这就是客户端通道。如何编写文件名(字符串)并在客户端读取它。我很困惑。即使我在服务器端注册客户端通道,我也只能对其进行写入。你能给我举个例子吗?我必须承认我没有使用通道,但无论如何,不能读写同一个通道似乎很奇怪,特别是因为上面说:>通道表示与硬件设备、文件、网络套接字等实体的开放连接,或能够执行一个或多个不同I/O操作(例如读或写)的程序组件。最好的方法是在服务器和客户端之间定义某种协议。你可以去看看。@CristiFati我以前也这么做过。在我的例子中,我创建了一个
    DataOutputStream来发送文件名和文件大小,然后创建了一个socketchanel
    来发送内容。此方法需要两个端口。我在想有一种方法可以在整个过程中只使用一个端口。为什么发送两个内容需要两个端口?使用相同的连接(和通道),需要交替执行读/写操作。@CristiFati我们只编写一个通道。这就是客户端通道。如何编写文件名(字符串)并在客户端读取它。我很困惑。即使我在服务器端注册客户端通道,我也只能对其进行写入。你能给我举个例子吗?我必须承认我没有使用通道,但无论如何,不能读写同一个通道似乎很奇怪,特别是因为上面说:>通道表示与硬件设备、文件、网络套接字等实体的开放连接,或者一个能够执行一个或多个不同I/O操作的程序组件,例如读或写。@SaitejaPrasadam您记得在文件中附加文件类型吗?e、 g
    fileName.txt
    @SaitejaPrasadam还确认包含文件名的字节没有与文件内容混淆。i