SOCKET PROBLEM: Server and client "deadlock"

Discussion in 'Java' started by Ramon, Feb 25, 2009.

  1. Ramon

    Ramon Guest

    Hello again,

    I'm writing a simple experimental file transfer server and client. The
    file can be a binary file.

    The problem is when:
    * Server finishes transferring a file and waits for the client's input.
    * Client, for some reason, "hangs" and waits for more data to be
    transfered, even though the file is fully transfered.
    * Thus, a deadlock occurs.

    Is the a way to solve this problem?

    /*
    * SERVER CODE -- 1st if sends a file to the client,
    * then it waits for a message from the client.
    */
    ServerSocket s = new ServerSocket(60001);
    String file = "/home/ramon/image.iso";

    while (true)
    {
    Socket clientSocket = s.accept();
    ObjectOutputStream out
    = new ObjectOutputStream( clientSocket.getOutputStream() );
    FileInputStream f = new FileInputStream(file);
    byte buffer[] = new byte[1024];

    System.err.println("Uploading file...");
    int size;
    while ( (size = f.read(buffer)) > 0 )
    out.write(buffer, 0, size);
    System.err.print("\t[DONE]\n");


    // waits for the client
    ObjectInputStream in = new ObjectInputStream(
    clientSocket.getInputStream() );
    String x = (String) in.readObject();
    System.out.println("Msg from client: >>" + x + "<<");

    clientSocket.close();
    f.close();
    }




    /*
    * CLIENT CODE: 1st it receives a file, then it
    * sends a message to the server.
    */
    Socket s = new Socket(InetAddress.getByName("127.0.0.1"), 60001);

    ObjectOutputStream outX = new ObjectOutputStream( s.getOutputStream() );
    ObjectInputStream in = new ObjectInputStream( s.getInputStream() );
    FileOutputStream fo = new FileOutputStream("/home/ramon/zdown/myfile.iso");
    byte buffer[] = new byte[1024];

    // downloads file
    System.err.println("Downloading...");
    int size;
    while ( (size = in.read(buffer)) > 0 )
    fo.write(buffer, 0, size);

    fo.close();
    System.err.println("File Downloaded.");


    // sends a message
    System.err.print("Type a message: ");
    Scanner scan = new Scanner(System.in);


    outX.writeObject((String) scan.nextLine());
    System.err.println("Data send");
    s.close();



    /*
    * OUTPUT FROM SERVER:
    */
    Uploading file...
    [DONE]


    /*
    * OUTPUT FROM CLIENT:
    */
    Downloading...
     
    Ramon, Feb 25, 2009
    #1
    1. Advertising

  2. Ramon wrote:

    > while (true)


    Why an endless loop if you describe a single write/read-step?

    > {
    > Socket clientSocket = s.accept();
    > ObjectOutputStream out
    > = new ObjectOutputStream( clientSocket.getOutputStream() );

    [...]
    > while ( (size = f.read(buffer)) > 0 )
    > out.write(buffer, 0, size);


    Why do you use an ObjectOutputStream and write the raw data
    directly? The instantiation of an ObjectOutputStream already
    leads to the write of some data, so if this data is also
    present in the iso-file, you send this data twice.

    > while ( (size = f.read(buffer)) > 0 )
    > out.write(buffer, 0, size);
    > System.err.print("\t[DONE]\n");


    Done without out.flush() is not done.

    > System.err.println("Downloading...");
    > int size;
    > while ( (size = in.read(buffer)) > 0 )
    > fo.write(buffer, 0, size);


    This will never finish as long as you keep open the OutputStream
    on the server-side. Only if you close it, the client will leave
    this call and the read-function will return -1

    If binary data being uploaded and a message being returned is
    all you exchange between the two peers, you shouldn't use
    ObjectOutputStream and ObjectInputStream. Both are caching
    all objects that have been sent/received leading to Out-
    OfMemoryErrors if this is a long-running process. The server
    and the client can easily switch to a BufferedOutputStream
    (don't forget the flush). The message can be sent by sending
    the length of converted byte-array (or -1 if it's null) and
    then the byte-array of the message that you retrieved by
    message.getBytes("UTF8"). On the server-side you simply create
    a String from that by doing a new String(bytes, "UTF8")


    Regards, Lothar
    --
    Lothar Kimmeringer E-Mail:
    PGP-encrypted mails preferred (Key-ID: 0x8BC3CD81)

    Always remember: The answer is forty-two, there can only be wrong
    questions!
     
    Lothar Kimmeringer, Feb 25, 2009
    #2
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Avizz
    Replies:
    3
    Views:
    13,823
    Andy Fish
    Sep 29, 2003
  2. greatestmclarenfan
    Replies:
    2
    Views:
    581
    Steve Horsley
    Feb 16, 2006
  3. Replies:
    1
    Views:
    482
    Greg Copeland
    Mar 21, 2007
  4. Laszlo Nagy
    Replies:
    1
    Views:
    4,858
    Mark Wooding
    Jan 27, 2009
  5. peter pilsl
    Replies:
    5
    Views:
    132
Loading...

Share This Page