如何在android中使用socket发送大文件

时间:2017-02-14 12:06:36

标签: java android sockets

我已编写此代码以将文件从服务器传输到客户端,但我只能发送少于1 Kb的文件大小。我想发送任何大小的文件。如果您可以修改我的代码,那将非常有用:

文件发件人(服务器代码)

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);
                }

文件接收者(客户端代码)

 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();

                    }

请帮助先生!提前致谢!

2 个答案:

答案 0 :(得分:2)

您需要将字节的接收放在一个循环中,该循环仅在收到所有数据时才完成。例如: -

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();

答案 1 :(得分:1)

我可以发誓你的原始问题是关于接收,而不是发送(和其他答案似乎表明相同)。

无论如何,要发送大文件,您可以将整个文件读入足够容纳它的缓冲区(假设文件大小合理),或者使用循环以可管理大小的块读取它然后处理(发送)块。

在回答原始问题时,您只阅读1024,因为这是您尝试阅读的全部内容。您已将缓冲区分配为1024并且只读取一次。

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

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);
}
...

并在遇到异常的情况下使用try / catch块将代码包装在适当的位置。