Question

I'm trying to implement basic communication through sockets, what I have now is:

  • server start's to listen on socket,

    this.serverSocket_ = new ServerSocket(this.serverPort_);
    clientSocket = this.serverSocket_.accept();
    
  • client connects, and server starts separate thread to operate with that client,

  • both open Object output and input streams,

    out = new ObjectOutputStream(clientSocket_.getOutputStream());
    out.flush();
    in = new ObjectInputStream(clientSocket_.getInputStream());
    
  • client sends two i Doubles, String and Long over that stream (flushes after each one),

        out.writeObject(conf_);
        out.flush();
        out.writeObject(supp_);
        out.flush();
        out.writeObject(separator_);
        out.flush();
        out.writeObject(new Long(dataFile_.length()));
        out.flush();
    
  • server succesfully receives those objects over previously opened streams,

    conf_ = (Double) in_.readObject();
    supp_ = (Double) in_.readObject();
    separator_ = (String) in_.readObject();
    fileSize_ = (Long) in_.readObject();
    
  • and now "the hard part",

  • clients wants to send a file so opens different output stream (not object output stream) and sends the file,

    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();
    
  • the server receives the file (also uses simple input stream instead 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();
    
  • so far everything works fine, file is received, but now server performs some time consuming processing on that file after which sends response with whe results to client,

    String resp = new String("Some processing result...");
    out_.writeObject(resp);
    out_.flush();
    
  • the client is supposed to receive the result what finishes the whole communication,

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

Unfortunately, that last step on client side fails with exception:

    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)

I want client to block on waiting for server response after sending the file, but it suddenly finishes with the exception after sending the file. I am pretty sure that I do something wrong with switching between simple streams and Object streams.

Does anybody know what should I change to haave it working?

Thank you in advance!

Was it helpful?

Solution

I think your basic misunderstanding is here:

clients wants to send a file so opens different output stream

OutputStream os = clientSocket_.getOutputStream();

That doesn't open a different output stream - that will get another reference to the same output stream which you've already got wrapped in the ObjectOutputStream. If you want two streams of data, you'll need to open two separate connections.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top