"java.io.EOFException" po przesłaniu pliku przez socket

0

Próbuję zaimplementować w Javie prostą komunikację za pośrednictwem socketów, to co mam to:

  • serwer nasłuchuje na sockecie,
this.serverSocket_ = new ServerSocket(this.serverPort_);
clientSocket = this.serverSocket_.accept();
  • klient się podłącza a serwer tworzy osobny wątek do jego obsługi,
  • serwer i klient otwierają ObjectInputStream i ObjectOutputStream,
out = new ObjectOutputStream(clientSocket_.getOutputStream());
out.flush();
in = new ObjectInputStream(clientSocket_.getInputStream());
  • klient wysyła dwa Double, String-a i Long-a poprzez otworzony strumień (po każdym robi flush-a),
out.writeObject(conf_);
out.flush();
out.writeObject(supp_);
out.flush();
out.writeObject(separator_);
out.flush();
out.writeObject(new Long(dataFile_.length()));
out.flush();
  • serwer pomyślnie odbiera przesłane obiekty,
conf_ = (Double) in_.readObject();
supp_ = (Double) in_.readObject();
separator_ = (String) in_.readObject();
fileSize_ = (Long) in_.readObject();

teraz trudna część,

  • klient chce wysłać plik więc otwiera zwykły OutputStream (nie ObjectOutputStream) i wysyła plik,
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();
  • serwer odbiera plik (również używa zwykłego InputStream-a zamiast 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;

//	Thread.sleep(1000);
} while ((bytesRead > -1) && (current < fileSize));

bos.write(mybytearray, 0, current);
bos.flush();
bos.close();
  • do tej pory wszystko działa, plik jest odebrany, ale w tym momencie serwer podejmuje czasochłonne obliczenia po których wysyła odpowiedź z wynikiem do klienta,
String resp = new String("Some processing result...");
out_.writeObject(resp);
out_.flush();
  • klient powinien odebrać wyniki co kończy komunikację,
String message = (String) in.readObject();
Console.info("server > " + message);

Niestety ostatni krok po stronie klienta kończy się rzuceniem wyjątku:

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)

Chciałbym aby klient zablokował się i oczekiwał na odpowiedź serwera po przesłaniu pliku, ale ten natychmiast kończy rzuceniem wyjątku po przesłaniu pliku. Jestem prawie pewien, że coś robię źle podczas przełączania się pomiędzy rodzajami strumieni (zwykłym i ObjectStream).

Czy ktoś jest w stanie podpowiedzieć mi co robię źle?

Z góry dzięki!

0

Może serwer zamyka swój strumień wejścia zanim wyśle odpowiedź?
Zakomentuj tymczasowo wszystkie odwołania do metody close() w swoim kodzie.

0

Może też się tak dziać w przypadku gdy w trakcie przesyłania pojawia się gdzieś zero binarne.

1 użytkowników online, w tym zalogowanych: 0, gości: 1