Manoj Gayakwad
Manoj Gayakwad

Reputation: 65

How to send large file using socket in android

I have written this code to transfer file from server to client, but i am able to send only less than 1 Kb size of file. i want to send any size of file. It would be very helpful if you could modify my code:

File Sender(Server code)

protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        infoIp = (TextView) findViewById(R.id.infoip);
        infoPort = (TextView) findViewById(R.id.infoport);

        infoIp.setText(getIpAddress());

        serverSocketThread = new ServerSocketThread();
        serverSocketThread.start();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();

        if (serverSocket != null) {
            try {
                serverSocket.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

    private String getIpAddress() {
        String ip = "";
        try {
            Enumeration<NetworkInterface> enumNetworkInterfaces = NetworkInterface.getNetworkInterfaces();
            while (enumNetworkInterfaces.hasMoreElements()) {
                NetworkInterface networkInterface = enumNetworkInterfaces.nextElement();
                Enumeration<InetAddress> enumInetAddress = networkInterface.getInetAddresses();

                while (enumInetAddress.hasMoreElements()) {
                    InetAddress inetAddress = enumInetAddress.nextElement();

                    if (inetAddress.isSiteLocalAddress()) {
                        ip += "SiteLocalAddress: "+ inetAddress.getHostAddress() + "\n";
                    }
                }
            }

        } catch (SocketException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            ip += "Something Wrong! " + e.toString() + "\n";
        }

        return ip;
    }

    public class ServerSocketThread extends Thread {

        @Override
        public void run() {
            Socket socket = null;

            try {
                serverSocket = new ServerSocket(SocketServerPORT);
                MainActivity.this.runOnUiThread(new Runnable() {

                    @Override
                    public void run() {
                        infoPort.setText("I'm waiting here: "
                                + serverSocket.getLocalPort());
                    }});

                while (true) {
                    socket = serverSocket.accept();
                    FileTxThread fileTxThread = new FileTxThread(socket);
                    fileTxThread.start();
                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } finally {
                if (socket != null) {
                    try {
                        socket.close();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    public class FileTxThread extends Thread {
        Socket socket;
        FileTxThread(Socket socket){
            this.socket= socket;
        }

        @Override
        public void run() {
            File file = new File(Environment.getExternalStorageDirectory(),"test.mp3");

            byte[] bytes = new byte[(int) file.length()];

            BufferedInputStream bis;
            try {
                bis = new BufferedInputStream(new FileInputStream(file));
                bis.read(bytes, 0, bytes.length);
                OutputStream os = socket.getOutputStream();
                os.write(bytes, 0, bytes.length);
                os.flush();
               // socket.close();

                final String sentMsg = "File sent to: " + socket.getInetAddress();
                System.out.println("socket getIntentAddress "+socket.getInetAddress());
                MainActivity.this.runOnUiThread(new Runnable() {

                    @Override
                    public void run() {
                        Toast.makeText(MainActivity.this,sentMsg,Toast.LENGTH_LONG).show();

                    }});

            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                System.out.println("Ioexception"+e);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
               } finally {
                try {
                    socket.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                    System.out.println("Ioexception"+e);
                }

File Receiver(Client Code)

 buttonConnect.setOnClickListener(new OnClickListener(){

            @Override
            public void onClick(View v) {
                ClientRxThread clientRxThread =
                        new ClientRxThread(editTextAddress.getText().toString(),SocketServerPORT);

                clientRxThread.start();
            }});
    }

    private class ClientRxThread extends Thread {
        String dstAddress;
        int dstPort;

        ClientRxThread(String address, int port) {
            dstAddress = address;
            dstPort = port;
        }

        @Override
        public void run() {
            Socket socket = null;

            try {
                socket = new Socket(dstAddress, dstPort);


                File file = new File(Environment.getExternalStorageDirectory(),"test.mp3");

                byte[] bytes = new byte[1024];


                InputStream is = socket.getInputStream();
                FileOutputStream fos = new FileOutputStream(file);
                BufferedOutputStream bos = new BufferedOutputStream(fos);
                int bytesRead = is.read(bytes, 0, bytes.length);
                bos.write(bytes, 0, bytesRead);
                bos.close();
               // socket.close();

                MainActivity.this.runOnUiThread(new Runnable() {

                    @Override
                    public void run() {
                        Toast.makeText(MainActivity.this,"Finished",Toast.LENGTH_LONG).show();
                    }});

            } catch (IOException e) {

                e.printStackTrace();

                final String eMsg = "Something wrong: " + e.getMessage();

                MainActivity.this.runOnUiThread(new Runnable() {

                    @Override
                    public void run() {
                        Toast.makeText(MainActivity.this,eMsg,Toast.LENGTH_LONG).show();
                        System.out.println("run"+eMsg);
                    }});

            } finally {
                if(socket != null){
                    try {

                        socket.close();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();

                    }

Please help Sir! Thanks in advance!

Upvotes: 4

Views: 3904

Answers (2)

Les
Les

Reputation: 10605

I could have sworn your original questions was about receiving, not sending (and other answers seem to suggest the same).

Regardless, to send large files, you can either read your entire file into a buffer large enough to hold it (assuming the file is of a reasonable size), or use a loop to read it in chunks of a manageable size and then process (send) the chunks.

In answer to your original question, you are only reading 1024 because that is all you are attempting to read. You have allocated your buffer at 1024 and only reading once.

            byte[] bytes = new byte[1024];
...
            int bytesRead = is.read(bytes, 0, bytes.length);
            bos.write(bytes, 0, bytesRead);
            bos.close();

try

byte[] bytes = new bytes[1024];
...
int bytesRead = is.read(bytes, 0, bytes.length);
while(bytesRead > 0) {
    bos.write(bytes, 0, bytesRead);
    bytesRead = is.read(bytes, 0, bytes.length);
}
...

and wrap your code at an appropriate spot with a try/catch block in case of an exception.

Upvotes: 2

Steve Smith
Steve Smith

Reputation: 2271

You need to put the receiving of the bytes in a loop that only completes when all the data has been received. For example:-

byte[] bytes = new byte[1024];
InputStream is = socket.getInputStream();
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file));
while (true) {
    int bytesRead = is.read(bytes);
    if (bytesRead < 0) break;
    bos.write(bytes, 0, bytesRead);
    // Now it loops around to read some more.
}
bos.close();

Upvotes: 2

Related Questions