0

私はJavaの初心者です。クライアントとサーバーの通信に問題があります。送信する複数のベクトルを読み取る方法がわかりません。私はあなたの助けに感謝します:)。私のコードは次のとおりです: サーバー:

import java.net.*;
import java.util.Vector;
import java.io.*;

   public class FileServer {
   private static ObjectOutputStream outStream;

   public static void main (String [] args ) throws IOException {

    // create socket
      ServerSocket servsock = new ServerSocket(2926);
   while (true) {
  System.out.println("Waiting...");


  Socket sock = servsock.accept();
  System.out.println("Accepted connection : " + sock);
  outStream = new ObjectOutputStream(sock.getOutputStream());
  // sendfile
  File myFile = new File ("D://music.mp3");


  Vector<Integer> send = new Vector<Integer>(); 
  int CRC=0;
  int part=0;
      for(int num=1;num<=(int) myFile.length()/60;num++){
          CRC= (part+num)%3;
          part = num*60;
          send.addElement(num);          
          send.addElement(part);
          send.addElement(CRC);
          outStream.writeObject(send);
          System.out.println(send);
          send.removeElement(num);
          send.removeElement(part);
          send.removeElement(CRC);

          if((myFile.length()<=(num+1)*60)&&(myFile.length()%60!=0)){
              int left = (int) (myFile.length()%60+part);
              int Num=num+1;
              CRC = (left + num)%2;

              send.addElement(Num);
              send.addElement(left);                 
              send.addElement(CRC);
              outStream.writeObject(send);
              System.out.println(send);
              send.removeElement(Num);
              send.removeElement(part);
              send.removeElement(CRC);



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

          }
    }
  outStream.close();

  sock.close();

}
}
}

サーバー側のエラー:

[1 60 1]
....
[64367, 3862020, 2]
[64368, 3862047, 0]
Sending...
Exception in thread "main" java.net.SocketException: Socket closed
  at java.net.SocketOutputStream.socketWrite(Unknown Source)
  at java.net.SocketOutputStream.write(Unknown Source)
  at java.io.ObjectOutputStream$BlockDataOutputStream.drain(Unknown Source)
  at java.io.ObjectOutputStream$BlockDataOutputStream.setBlockDataMode(Unknown Source)
  at java.io.ObjectOutputStream.writeNonProxyDesc(Unknown Source)
  at java.io.ObjectOutputStream.writeClassDesc(Unknown Source)
  at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
  at java.io.ObjectOutputStream.writeObject0(Unknown Source)
  at java.io.ObjectOutputStream.writeFatalException(Unknown Source)
  at java.io.ObjectOutputStream.writeObject(Unknown Source)
  at FileServer.main(FileServer.java:61)

私のクライアント側:

import java.net.*;
import java.util.Vector;
import java.io.*;

public class FileClient{

private static InetAddress host; 
public static void main (String [] args ) throws ClassNotFoundException,    UnknownHostException, IOException {

  host = InetAddress.getLocalHost();
  Socket sock = new Socket(host,2926);
  System.out.println("Connecting...");
  ObjectInputStream inStream = new ObjectInputStream(sock.getInputStream());

  long start = System.currentTimeMillis();

  for(int a=1;a<=100;a++){
  System.out.println("seq number of received vector: "+a);

  @SuppressWarnings("unchecked")   
  Vector <send> response = (Vector<send>)inStream.readObject();
  long end = System.currentTimeMillis();
  System.out.println(response);
  System.out.println("time: "+(end-start));


  }


  sock.close();


}


 }

クライアント側からのエラー: (エラーはありませんが、最初のベクトルの 100 倍ではなく、少なくとも 100 個のベクトルを表示したい):

seq number of received vector: 1
[1, 60, 1]
time: 71
...
seq number of received vector: 100
[1, 60, 1]
time: 79
4

2 に答える 2

1

オブジェクトが出力ストリームに書き込まれると、それを 2 回目に送信すると、ストリームは既に送信されたものへの参照のみを送信します。そのため、毎回新しいベクターを作成するか、ベクターを 2 回目に送信する前にストリームでreset()を呼び出します。

ここ数年、ArrayList は Vector よりも優先されるべきであることに注意してください。Vector はもう使用しないでください。

于 2012-07-29T12:07:27.247 に答える
0

サーバー側の例外の場合。クライアントは、100 個のベクトルを読み取った後にソケットを閉じます。サーバー側にはまだ書き込むベクトルがあります。そのため、「java.net.SocketException: ソケットが閉じられました」と報告されました

クライアントの「繰り返しの問題」についてはnew、送信ループで毎回ベクターを作成する必要があります

内部では、Java ObjectOutputStream/InputStream はシリアル化されたすべてのオブジェクトの「参照」を記憶するため、クライアント側でオブジェクト参照マップを再構築できます。オブジェクトが以前にシリアル化されて送信された場合、「参照」のみがマークされて送信されます。あなたの場合、単一のオブジェクトが書き込まれ、クライアントは単一のオブジェクトのみを受け取ります。詳細については、ソースコードを掘り下げてくださいwriteObject

于 2012-07-29T12:45:27.260 に答える