1

私のプロジェクトクライアントでは、いくつかのテキストといくつかの画像をサーバーに送信します。サーバーはこれらすべてを処理する必要があります。つまり、テキストが存在する場合はフレーム上にあるTestAreaに表示する必要があり、画像ファイルが存在する場合はサーバーはその画像ファイルをコンピューターに保存する必要があります。文字列(テキスト)または画像ファイルのいずれかを処理する1つのアプリケーションを作成しましたが、これらがクライアントから同時に送信されるときに、これらすべてを保存する方法がわかりません。

このコードを追加すると、次のようになります 。InputStream in = socket.getInputStream();

クライアントから送信されるすべてのデータはこのInputStreamにあります。 したがって、これまでの範囲のデータを識別する方法は画像ファイルであるため、バイト配列に格納する必要があります。これまではテストまたは文字列であるため、TextAreeaで表示する必要があります。クライアントが一度に2つ以上の画像をサーバーに送信する場合、サーバーがこの量のデータまでこれが最初の画像であり、これまでの量のデータまでこれが2番目の画像ファイルであることをサーバーがどのように理解するか。

私は画像を送信するためにこのコードを試しました:

クライアントコード:

public void sendPhotoToServer(String str){ // str is image location
try {
    InputStream input = new FileInputStream(str);
    byte[] buffer=new byte[1024];
    int readData;
    while((readData=input.read(buffer))!=-1){
    dos.write(buffer,0,readData); // dos is DataOutputStream
    }
} catch (FileNotFoundException e) {

} catch (IOException e) {

}       
}

このメソッドはループ内にあるため、クライアントは自分のフォルダー内のすべての画像を送信します。

サーバーコードです。これはスレッド内にあり、whileループがあり、毎回クライアントデータをリッスンします。

public void run() {
while (true) {
        try {
            byte[] buffer = new byte[8192];
            fis = new FileOutputStream("C:\\"+(s1++)+".jpg"); // fis is FileOutputStream
            while ((count = in.read(buffer)) > 0){ //count is a integer and 'in' is InputStream
            fis.write(buffer, 0, count); 
            fis.flush();    
            }
            } catch (Exception e) {}
}
}

ただし、このコードでは、最初の画像がサーバーによって受信され、その後、他の画像は表示されません。

ここでは、単純な文字列がクライアントによって送信されたかどうかをサーバーがどのように理解するかを示します。サーバー側のアプリケーションでは、1つのポートを開いて、クライアントから送信されたすべてのデータをリッスンします。

FileOutputStream fis = socket.getInputStream();

これらすべてのファイルと単純な文字列をどのように区別するかを説明します。

4

3 に答える 3

2

データ境界の自動処理はありません。サーバーコードには、一方のファイル/メッセージがどこで終了し、もう一方がどこで開始するかを知る方法がありません。独自のプロトコルを考え出す必要があります。

于 2012-04-04T13:02:16.060 に答える
2

事前にデータ型がわかっている場合は、ObjectInputStreamandを使用してみませんか。ObjectOutputStream

送信は次のとおりです。

import java.io.*;

public class Client {

  public static void main(String[] args) throws IOException {
    // write string
    ObjectOutputStream out = new ObjectOutputStream(
      new BufferedOutputStream(
        new FileOutputStream("test-string.data")));
    try {
      out.writeObject("Hello");
    } finally {
      out.close();
    }
    // write byte arrays
    out = new ObjectOutputStream(
      new BufferedOutputStream(
        new FileOutputStream("test-byteArrays.data")));
    try {
      out.writeObject(new byte[] { 'H', 'e', 'l', 'l', 'o' });
      out.writeObject(new byte[] { 'W', 'o', 'r', 'l', 'd' });
    } finally {
      out.close();
    }
  }

}

ここに受け取ります:

import java.io.*;
import java.util.*;

public class Server {

  public static void main(String[] args) throws IOException, ClassNotFoundException {
    // write string
    ObjectInputStream in = new ObjectInputStream(
      new BufferedInputStream(
        new FileInputStream("test-string.data")));
    try {
      Object o = null;
      while ((o = in.readObject()) != null) {
        System.out.printf("Class: %s, toString: %s\n", o.getClass(), o.toString());
      }
    } catch (EOFException e) {
      // finished
    } finally {
      in.close();
    }
    // write byte arrays
    in = new ObjectInputStream(
      new BufferedInputStream(
        new FileInputStream("test-byteArrays.data")));
    try {
      Object o = null;
      while ((o = in.readObject()) != null) {
        System.out.printf("Class: %s, toString: %s\n", o.getClass(), o.toString());
      }
    } catch (EOFException e) {
      // finished
    } finally {
      in.close();
    }
  }

}
于 2012-04-04T13:54:20.390 に答える
1

あなたがしているのは、ソケットを介して生データを送信することです。あなたが持っているのはそれだけです:バイトのストリーム。受信側がどの部分がどのファイルに属しているか、およびこのファイルのタイプを確実に理解できるようにするには、実際のデータがバイトストリームにエンコードされるようにこれをエンコードする方法を考え出す必要があります。邪魔されず、送信者と受信者の両方がこの構造を「理解」します。これは、プロトコルとして知られている種類のものです。

独自のプロトコルを考え出すことは状況によっては役立つ場合がありますが、達成したいことに基づいて非常に複雑になる可能性があることを知っておいてください。ほとんどの場合、ニーズに適したプロトコルがすでに存在します。ヘッダーフィールドに示されているMIMEタイプでHTTPを使用できます。これにより、ファイルタイプと、テキストの場合はエンコーディングを把握できます。FTPはファイル転送に適しており、ファイル名の拡張子を使用してそのタイプを検出できます。SOAPを使用すると、クライアントまたはサーバーの実装言語に依存しない方法で複雑なデータ構造を送信できます。

TL; DRバージョン:車輪の再発明をせずに、ニーズに合ったものを探しましょう。ほとんどの場合、適切なプロトコルは、Javaですぐに使用できるか、サードパーティのライブラリを介してサポートされています。ここでは、ApacheのCommonsNetが役立ちます。

于 2012-04-04T13:30:35.387 に答える