user3089869
user3089869

Reputation: 229

Packet loss in socket programming java

I am trying to send a file from client to server. Below is the code i have tried. But at times, there is a packet loss during the transfer. I am not sure where i am wrong.

SERVER SIDE CODE:

public static void ReadAndWrite(byte[] aByte, Socket clientSocket,
            InputStream inputStream, String fileOutput)
                    throws FileNotFoundException, IOException {
        int bytesRead;
        FileOutputStream fileOutputStream = null;
        BufferedOutputStream bufferedOutputStream = null;
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        try
        {
        fileOutputStream = new FileOutputStream( fileOutput );
        bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
        bytesRead = inputStream.read(aByte, 0, aByte.length);
        System.out.println("The length is "+bytesRead);
        int count = 0;
        do {
            count++;
            byteArrayOutputStream.write(aByte);
            bytesRead = inputStream.read(aByte);
        } while (bytesRead != -1);
        System.out.println("The count is "+count);
        System.out.println("The length is "+byteArrayOutputStream.size());
        bufferedOutputStream.write(byteArrayOutputStream.toByteArray());
        bufferedOutputStream.flush();
        bufferedOutputStream.close();
        clientSocket.close();
        }
        catch(Exception ex)
        {
            Logger.writeLog(ex,Listen.class.getName(), LogType.EXCEPTION);  
            throw ex;
        }

CLIENT SIDE CODE:

public  void readByteArrayAndWriteToClientSocket(
            Socket connectionSocket, BufferedOutputStream outToClient, String fileToSend ) throws Exception
    {
        try{
        if (outToClient != null) 
        {
            File myFile = new File(fileToSend);
            System.out.println(myFile.length());
            byte[] byteArray = new byte[(int) myFile.length()];

            FileInputStream fileInputStream = null;

            try {
                fileInputStream = new FileInputStream(myFile);
            } catch (IOException ex) {
                Logger.writeLog(ex, FileUtility.class.getName(), LogType.EXCEPTION);
                throw ex;
            }
            BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);

            try {
                bufferedInputStream.read(byteArray, 0, byteArray.length);
                outToClient.write(byteArray, 0, byteArray.length);
                outToClient.flush();
                outToClient.close();
                connectionSocket.close();


                return;
            } catch (IOException ex) {
                Logger.writeLog(ex, FileUtility.class.getName(), LogType.EXCEPTION);
                throw ex;
            }

        }
        }catch (Exception e) {
            Logger.writeLog(e, getClass().getName(), LogType.EXCEPTION);
            throw e;
        }
    }

Upvotes: 1

Views: 4474

Answers (2)

user207421
user207421

Reputation: 310884

There is no 'packet loss', just bugs in your code.

The canonical way to copy a stream in Java is as follows:

while ((count = in.read(buffer)) > 0)
{
   out.write(buffer, 0, count);
}

If you know the number of bytes in advance and the sender must keep the connection open after the transfer, it becomes:

while (total < expected && (count = in.read(buffer, 0, expected-total > buffer.length ? buffer.length : (int)(expected-total))) > 0)
{
   out.write(buffer, 0, count);
   total += count;
}

Forget all the ByteArrayInput/OutputStreams and the extra copies. Just read from the file and send to the socket, or read from the socket and write to the file.

Upvotes: 4

James Anderson
James Anderson

Reputation: 27478

The sockets read method will return when its has obtained all the bytes you asked for, OR, when it stops receiving data from the network.

As transmission is often interrupted in any real network you need to keep issuing read calls until you have the number of bytes you want.

You need code something like this:

        char [] buffer = new char[1024];
        int expect = 1000;
        int sofar = 0;
       int chars_read;
       try
       {
          while((chars_read = from_server.read(buffer[sofar])) != -1)
          {
             sofar = sofar + chars_read;
             if (sofar >= expected) break;
          }
       }
       catch(IOException e)
       {
          to_user.println(e);
       }

Upvotes: 3

Related Questions