1

私はソケットを介して基本的な通信を実装しようとしています。今持っているものは次のとおりです。

  • サーバーはソケットでリッスンし始めます。

    this.serverSocket_ = new ServerSocket(this.serverPort_);
    clientSocket = this.serverSocket_.accept();
    
  • クライアントが接続し、サーバーが別のスレッドを開始してそのクライアントで動作し、

  • オブジェクトの出力ストリームと入力ストリームの両方を開きます。

    out = new ObjectOutputStream(clientSocket_.getOutputStream());
    out.flush();
    in = new ObjectInputStream(clientSocket_.getInputStream());
    
  • クライアントは、そのストリームを介して 2 つの i Double、String、および Long を送信します (それぞれの後にフラッシュします)。

        out.writeObject(conf_);
        out.flush();
        out.writeObject(supp_);
        out.flush();
        out.writeObject(separator_);
        out.flush();
        out.writeObject(new Long(dataFile_.length()));
        out.flush();
    
  • サーバーは、以前に開いたストリームを介してこれらのオブジェクトを正常に受信し、

    conf_ = (Double) in_.readObject();
    supp_ = (Double) in_.readObject();
    separator_ = (String) in_.readObject();
    fileSize_ = (Long) in_.readObject();
    
  • そして今、「難しい部分」、

  • クライアントがファイルを送信したいので、別の出力ストリーム (オブジェクト出力ストリームではない) を開き、ファイルを送信します。

    FileInputStream fis = new FileInputStream(dataFile_);
    BufferedInputStream bis = new BufferedInputStream(fis);
    OutputStream os = clientSocket_.getOutputStream();
    
    while (current < fileSize) {
        bytesRead = bis.read(mybytearray, 0, mybytearray.length);
        if (bytesRead >= 0) {
            os.write(mybytearray, 0, mybytearray.length);
            current += bytesRead;
        }
        progressBar_.setValue(current);
        progressBar_.repaint();
    }
    os.flush();
    
  • サーバーはファイルを受信します (ObjectInputStream の代わりに単純な入力ストリームも使用します)。

    int bytesRead;
    int current = 0;
    
    tmpFile_ = File.createTempFile("BasketAnalysis", "rec.dat");
    
    byte[] mybytearray = new byte[fileSize];
    InputStream is = clientSocket_.getInputStream();
    FileOutputStream fos = new FileOutputStream(tmpFile_);
    BufferedOutputStream 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) && (current < fileSize));
    
    bos.write(mybytearray, 0, current);
    bos.flush();
    bos.close();
    
  • これまでのところ、すべてが正常に機能し、ファイルが受信されましたが、サーバーはそのファイルに対して時間のかかる処理を実行し、その後クライアントに結果を含む応答を送信します。

    String resp = new String("Some processing result...");
    out_.writeObject(resp);
    out_.flush();
    
  • クライアントは、通信全体を終了する結果を受け取ることになっています。

    String message = (String) in.readObject();
    Console.info("server > " + message);
    

残念ながら、クライアント側の最後のステップは例外で失敗します:

    java.io.EOFException
        at java.io.ObjectInputStream$BlockDataInputStream.peekByte(Unknown Source)
        at java.io.ObjectInputStream.readObject0(Unknown Source)
        at java.io.ObjectInputStream.readObject(Unknown Source)
        at basketAnalysis.client.Client.run(Client.java:74)
        at java.lang.Thread.run(Unknown Source)

ファイルの送信後にサーバーの応答を待ってクライアントをブロックしたいのですが、ファイルの送信後に突然例外で終了します。単純なストリームとオブジェクト ストリームを切り替える際に何か問題があると確信しています。

それを機能させるために何を変更すればよいか誰かが知っていますか?

前もって感謝します!

4

1 に答える 1

3

あなたの基本的な誤解はここにあると思います:

クライアントはファイルを送信したいので、別の出力ストリームを開きます

OutputStream os = clientSocket_.getOutputStream();

それは別出力ストリームを開きませObjectOutputStreamん.. 2 つのデータ ストリームが必要な場合は、2 つの別個の接続を開く必要があります。

于 2011-10-30T14:02:37.780 に答える