如何(无需每次重新连接和关闭套接字)从Android或java中的套接字接收许多文件

时间:2013-01-13 14:41:59

标签: java sockets

目前,我的服务器程序能够从客户端套接字接收文件,并能够将接收到的文件保存在服务器机器中。 但我需要从客户端套接字到服务器套接字接收许多文件,而不是每次关闭和打开套接字连接。

我已经编写了代码,这很好用。但在这里我将关闭并在每次迭代中打开服务器和客户端套接字连接。但我每次都不需要连接和断开两个插座就可以做到这一点。

请指导前辈......


我的服务器代码:

        int img_count=1;
        int bytesRead;
        int current = 0;
        byte [] mybytearray  = new byte [100000];

        InputStream is = null;
        FileOutputStream fos = null;
        BufferedOutputStream bos = null;
        Socket sock=null;

        // create socket
        ServerSocket servsock = new ServerSocket(6668);
        System.out.println("Waiting... for client req");
        int i=0;


         for ( i=0; i<9; i++)
          {

              sock = servsock.accept();        // Waiting for Client

              String fname = "Image000"+(img_count++)+".JPG";
              String fpath = "C:/RX_images/"+fname;      // Image saving path
              File myFile = new File (fpath);

              is = sock.getInputStream(); 
              fos = new FileOutputStream(myFile);
              bos = new BufferedOutputStream(fos);
              bytesRead = is.read(mybytearray,0,mybytearray.length);
              current = bytesRead;

           do {
              bytesRead =
              is.read(mybytearray, current, (mybytearray.length-current));
              if(bytesRead >= 0) current += bytesRead;
            } while(bytesRead > -1);

              bos.write(mybytearray, 0 , current);

              bos.flush();
              fos.flush();
              fos.close();
              bos.close();
              is.close();
              sock.close();

          }  // End of for loop

          servsock.close();
          System.out.println("Received : "+ (i++)+ " Images");

我的客户代码:

        int i=0;  
        int img_count=1;
        FileInputStream fis=null;
        BufferedInputStream bis=null;
        OutputStream os=null;
        Socket client=null;

        System.out.println("Sending...");


      for ( i=0; i<9; i++)
      {
          client = new Socket("192.168.1.54",6668);    

          String fname = "Image000"+(img_count++)+".JPG";
          String fpath = "C:/Tx_Images/"+fname;          // Image path
          File myFile = new File (fpath);

          byte [] mybytearray  = new byte [(int)myFile.length()];

          fis = new FileInputStream(myFile);
          bis = new BufferedInputStream(fis);        
          bis.read(mybytearray,0,mybytearray.length);
          os = client.getOutputStream();        
          os.write(mybytearray,0,mybytearray.length);

          bis.close();
          fis.close();
          os.flush();
          os.close();
          client.close();
          Thread.sleep(2000); 

      }   // End of for loop

      System.out.println("\n Sent : "+(i++)+" Images");

我是java的新手, 请帮帮我....

3 个答案:

答案 0 :(得分:0)

由于套接字只是一个字节流,为了处理多个文件,您将不得不构建某种简单的协议。换句话说,发送方必须发送区分一个文件中的字节和另一个文件中的字节的字节。由于您正在发送二进制数据,因此没有一系列字节可以发送以“标记”开头和/或/结尾 - 例如,如果您在结尾发送4个零字节,则可能是数据,因此接收器不能确定它是标记还是数据。有两种方法可以处理它 - 将文件分成最多N个字节的部分,并一次发送一个部分。您必须对每个部分中的字节数进行计数,因为至少有一个部分的字节数与所有其他部分的字节数不同。或者,您可以计算文件中的字节数,并从提供该计数的字节开始,因此接收方知道要预期的字节数。当您提供计数时,如果需要,您还可以提供文件名称和类型等信息。祝你好运。

答案 1 :(得分:0)

这个问题实际上取决于您是否需要客户端保持连接打开。通常,您只需要让服务器端保持监听,客户端每次需要发送文件时都可以重新连接。

使用ExecutorService保持服务器端的运行并使用单独的线程处理多个连接。然后让客户端连接并发送它需要发送和断开的内容。请参阅此问题以获取快速示例:Multithreading Socket communication Client/Server

另外,看看他们如何关闭资源(最后)并在该示例中停止服务器。这与您的问题无关,但您也希望使您的I / O和错误处理更加健壮。

如果您确实要求服务器和客户端保持连接并发送多个文件(或任何数据),那么您需要实现某种协议,如rcook所述,您需要深入了解网络并有一个心跳等。而且,即使您这样做,客户端仍然需要足够智能,以便在套接字关闭时尝试重新连接等。

答案 2 :(得分:0)

只需制作简单的协议:

 File Name\r\n
 File Size\r\n
 File Data\r\n
 File Name\r\n
 File Size\r\n
 File Data\r\n
 ....

我希望你能理解这一点。您最初可以发送文件信息,然后服务器将解析此文件信息,并使您的服务器读取您在文件信息中指定的数字字节。这些将使您能够查看文件结束标记以及何时开始新文件。但你必须知道文件大小。

这对于长度未知的数据流不起作用。

让您的服务器读取您将指定的字节数,以便服务器可以知道何时结束文件写入并开始新文件,或者在套接字关闭之前是否完全接收文件...