Sunshine
Sunshine

Reputation: 1

Send a stop message in a socket

I want a efficient and a fast way of sending a stop message in a socket.

I have a method that send files from one pc to another. All of the files from the sender appear on the receiver's PC. However all of the data is being written to the first file (only). The other files exist, but are empty. This happen because the receiver method doesn't know when to start writing to the next file.

Sender

public static void sendFile (final Socket sock, File source)
{
    FileInputStream fileIn = null;

    try
{
        //Read bytes from the source file
        fileIn = new FileInputStream(source);

        //Write bytes to the receive
        //No need to use a buffered class, we make our own buffer.
        OutputStream netOut = sock.getOutputStream();

        byte[] buffer = new byte[BUFFER_SIZE];
        int read;

        while ((read = fileIn.read(buffer)) != -1)
        {
            netOut.write(buffer, 0, read);
            netOut.flush ();
        }
        //Send some stop message here
}
    catch (Exception e)
{
        e.printStackTrace ();
}
    finally
    {
        if (fileIn != null)
        {
            try
            {
                fileIn.close ();
            }
            catch (IOException e)
            {
                e.printStackTrace ();
            }
        }
    }
}

//Send files via socket
public static void sendFile (final Socket sock, File[] source)
{
    for (int i = 0; i < source.length; i++)
        sendFile (sock, source[i]);
}

Receiver:

public static void receiveFile (final Socket sock, File destination)
{
    BufferedOutputStream out = null;

    try
    {
        //Receive data from socket
        InputStream clientInputStream = sock.getInputStream();

        //Write bytes to a file
        out = new BufferedOutputStream (new FileOutputStream (destination));

        byte[] buffer = new byte[BUFFER_SIZE];
        int read;
        while (true)
        {
            read = clientInputStream.read(buffer);


            out.write(buffer, 0, read);
            out.flush ();
        }
    }
    catch (IOException e)
    {
        e.printStackTrace ();
    }
    finally
    {
        if (out != null)
        {
            try
            {
                out.close ();
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
        }
    }
}

//Receive files via socket
public static void receiveFile (final Socket sock, File[] destination)
{
    for (int i = 0; i < destination.length; i++)
        receiveFile (sock, destination[i]);
}

Upvotes: 0

Views: 346

Answers (2)

Sunshine
Sunshine

Reputation: 1

I tried with a header like you suggested, but it doesn't work. The receiver still don't know when to stop(so I get EOFException). All the received data get written to the first file.

public static void sendFile (Socket sock, File source)
{
    FileInputStream fileIn = null;

    try
    {
        //Read bytes from the source file
        fileIn = new FileInputStream(source);

        //Write bytes to the receive
        //No need to use a buffered class, we make our own buffer.
        OutputStream netOut = sock.getOutputStream();

        byte[] buffer = new byte[BUFFER_SIZE];
        int readBytes = 0;
        long fileSize = source.length();
        long counter = 0;

        //Send the file size
        DataOutputStream objOut = new DataOutputStream (netOut);
        System.out.println ("Writing: " + source.length ());
        objOut.writeLong (fileSize);
        objOut.flush ();

        while ((counter += readBytes) < fileSize)
        {
            readBytes = fileIn.read(buffer);
            netOut.write(buffer, 0, readBytes);
            netOut.flush ();
        }
        fileIn.close();
    }
    catch (Exception e)
    {
        e.printStackTrace ();
    }
    finally
    {
        if (fileIn != null)
        {
            try
            {
                fileIn.close ();
            }
            catch (IOException e)
            {
                e.printStackTrace ();
            }
        }
    }
}

[]

public static void receiveFile (Socket sock, File destination)
{
    BufferedOutputStream fileOut = null;

    try
    {
        //Receive data from socket
        InputStream netIn = sock.getInputStream();

        //Write bytes to a file
        fileOut = new BufferedOutputStream (new FileOutputStream (destination));

        byte[] buffer = new byte[BUFFER_SIZE];
        int readBytes = 0;
        long fileSize;
        long counter = 0;

        //Receive the file size
        DataInputStream objIn = new DataInputStream (netIn);
        fileSize = objIn.readLong ();
        System.out.println ("Receiving: " + fileSize);

        while (true)
        {
            readBytes = netIn.read (buffer);
            fileOut.write (buffer, 0, readBytes);
            fileOut.flush ();

            counter += readBytes;
            if (counter > fileSize)
                break;
        }
    }
    catch (IOException e)
    {
        e.printStackTrace ();
    }
    finally
    {
        if (fileOut != null)
        {
            try
            {
                fileOut.close ();
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
        }
    }
    System.out.println ("Ending method");
}

Upvotes: 0

mah
mah

Reputation: 39847

You need to modify your send/receive protocol to include at least a minimal header before sending the file. Your header should include at least the size of the data to follow, and anything else you might want (such as file name).

Upvotes: 2

Related Questions