1

現在、My Server プログラムはクライアント ソケットからファイルを受信し、受信したファイルをサーバー マシンに保存できます。しかし、毎回ソケット接続を閉じたり開いたりすることなく、クライアントソケットからサーバーソケットに多くのファイルを受信する必要があります。

私はコードを書きました、これはうまくいきます。しかし、これでは、反復ごとにサーバーとクライアントのソケット接続を閉じたり開いたりしています。しかし、毎回両方のソケットを接続したり切断したりせずにこれを行う必要があります。

先輩方教えてください…


私のサーバーコード:

        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に非常に慣れていないので、助けてください....

4

3 に答える 3

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
 ....

これを理解していただければ幸いです。最初にファイル情報を送信すると、サーバーはこのファイル情報を解析し、ファイル情報で指定したバイト数をサーバーに読み取らせます。これらにより、ファイルの終了マーカーと、いつ新しいファイルを開始するかを確認できます。ただし、事前にファイルサイズを知っておく必要があります。

これは、長さが不明なデータ ストリームでは機能しません。

サーバーが指定するバイト数を読み取るようにします。これにより、サーバーは、ファイルの書き込みをいつ終了して新しいファイルを開始するか、またはソケットが閉じる前にファイルが完全に受信されたかどうかを知ることができます...

于 2013-01-13T17:38:19.930 に答える
0

ソケットは単なるバイト ストリームであるため、複数のファイルを処理するには、何らかの単純なプロトコルを構築する必要があります。つまり、送信者は、あるファイルのバイトと別のファイルのバイトを区別するバイトを送信する必要があります。バイナリデータを送信しているため、開始および/または終了を「マーク」するために送信できる一連のバイトはありません。たとえば、最後に4つのゼロバイトを送信すると、それはデータである可能性があるため、受信者それがマーカーかデータかを確認してください。それを処理する 2 つの方法がすぐに頭に浮かびます。ファイルを最大 N バイトのセクションに分割し、セクションを 1 つずつ送信します。少なくとも 1 つのセクションのバイト数が他のすべてのセクションと同じではないため、各セクションのバイト数を確認する必要があります。あるいは、y ファイル内のバイト数をカウントし、そのカウントを与えるバイト数から始めることができるので、受信者は期待するバイト数を知ることができます。数を指定するときに、必要に応じてファイルの名前や種類などの情報を指定することもできます。幸運を。

于 2013-01-13T15:12:02.553 に答える
0

この質問は、クライアントが接続を開いたままにしておく必要があるかどうかによって大きく異なります。通常、サーバー側をリッスンし続ける必要があるだけで、クライアントがファイルを送信する必要があるたびに再接続してもかまいません。

を使用しExecutorServiceてサーバー側を維持し、個別のスレッドで複数の接続を処理します。次に、クライアントに接続して、送信して切断する必要があるものを送信させるだけです。簡単な例については、この質問を参照してください:マルチスレッド ソケット通信 クライアント/サーバー

また、その例でリソースを (最終的に) クローズし、サーバーを停止する方法も見てください。それはあなたの質問とは関係ありませんが、I/O とエラー処理をより堅牢にする必要があります。

サーバーとクライアントの接続を維持し、複数のファイル (または任意のデータ) を送信することが本当に必要な場合は、rcook notes としてある種のプロトコルを実装する必要があります。心拍数など。そして、それを行ったとしても、クライアントはソケットが閉じられた場合などに再接続を試みるのに十分なほどスマートである必要があります.

于 2013-01-13T16:03:22.990 に答える