羊皮书APP(Android版)开发系列(十二)Android

作者: JeenWang | 来源:发表于2016-03-25 08:46 被阅读690次

    Tcp和IP协议是很重要的内容,但是要理解这些协议最好的方式就是自己根据业务写一些demo,加深理解。

    业务需求是:通过电脑端(网页或客户端形式)发送文件到Android的客户端,下面是使用UDP实现的一个简单的文件传输Demo,因UDP为不可靠传输,可能会丢包。

    • 服务器端发送本地文件,代码如下:
    package client;
    
    import server.udp.UDPUtils;
    
    import java.io.IOException;
    import java.io.RandomAccessFile;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetAddress;
    import java.net.InetSocketAddress;
    
    public class UDPClient {
    
        private static final String SEND_FILE_PATH = "/Users/wangjie/Documents/123.mp4";
    
        public static void main(String[] args){
            long startTime = System.currentTimeMillis();
    
            byte[] buf = new byte[UDPUtils.BUFFER_SIZE];
            byte[] receiveBuf = new byte[1];
    
            RandomAccessFile accessFile = null;
            DatagramPacket dpk = null;
            DatagramSocket dsk = null;
            int readSize = -1;
            try {
                accessFile = new RandomAccessFile(SEND_FILE_PATH,"r");
    //            dpk = new DatagramPacket(buf, buf.length,new InetSocketAddress(InetAddress.getByName("localhost"), UDPUtils.PORT + 1));
                dpk = new DatagramPacket(buf, buf.length,new InetSocketAddress(InetAddress.getByName("192.168.1.119"), UDPUtils.PORT + 1));
                dsk = new DatagramSocket(UDPUtils.PORT);
                int sendCount = 0;
                while((readSize = accessFile.read(buf,0,buf.length)) != -1){
                    System.out.println("readSize:"+readSize);
                    dpk.setData(buf, 0, readSize);
                    dsk.send(dpk);
                    // wait server response
                    {
                        while(true){
                            dpk.setData(receiveBuf, 0, receiveBuf.length);
                            dsk.receive(dpk);
    
                            // confirm server receive
                            if(!UDPUtils.isEqualsByteArray(UDPUtils.successData,receiveBuf,dpk.getLength())){
                                System.out.println("resend ...");
                                dpk.setData(buf, 0, readSize);
                                dsk.send(dpk);
                            }else
                                break;
                        }
                    }
    
                    System.out.println("send count of "+(++sendCount)+"!");
                }
                // send exit wait server response
                while(true){
                    System.out.println("client send exit message ....");
                    dpk.setData(UDPUtils.exitData,0,UDPUtils.exitData.length);
                    dsk.send(dpk);
    
                    dpk.setData(receiveBuf,0,receiveBuf.length);
                    dsk.receive(dpk);
                    // byte[] receiveData = dpk.getData();
                    if(!UDPUtils.isEqualsByteArray(UDPUtils.exitData, receiveBuf, dpk.getLength())){
                        System.out.println("client Resend exit message ....");
                        dsk.send(dpk);
                    }else
                        break;
                }
            }catch (Exception e) {
                e.printStackTrace();
            } finally{
                try {
                    if(accessFile != null)
                        accessFile.close();
                    if(dsk != null)
                        dsk.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
    
            long endTime = System.currentTimeMillis();
            System.out.println("time:"+(endTime - startTime));
        }
    }
    
    • 客户端接收文件存到本地,代码如下:
    package cn.studyou.androidsocket;
    
    
    import android.app.Activity;
    import android.os.Bundle;
    import android.os.Environment;
    import android.util.Log;
    
    import java.io.BufferedOutputStream;
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetAddress;
    import java.net.InetSocketAddress;
    
    public class UDPReceiveFileActivity extends Activity {
    
        private String localUrl;
        private static final String FILE_DIR = Environment.getExternalStorageDirectory().getAbsolutePath() + "/VideoCache/";
        private static final String SAVE_FILE_PATH = Environment.getExternalStorageDirectory().getAbsolutePath() + "/VideoCache/";
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_udpfile_mplayer);
    
            Log.e("FILE_DIR", FILE_DIR);
            new Thread(new Runnable() {
                @Override
                public void run() {
                    receiveFile();
                }
            }).start();
        }
        public void receiveFile() {
    
            byte[] buf = new byte[UDPUtils.BUFFER_SIZE];
    
            DatagramPacket dpk = null;
            DatagramSocket dsk = null;
            BufferedOutputStream bos = null;
            try {
                InetAddress loc = InetAddress.getByName("192.168.1.107");
    
                dpk = new DatagramPacket(buf, buf.length, new InetSocketAddress(loc, UDPUtils.PORT));
                dsk = new DatagramSocket(UDPUtils.PORT + 1);
    
                if (localUrl == null) {
                    localUrl = SAVE_FILE_PATH + "1235.mp4";
                }
                File cacheFile = new File(localUrl);
    
                if (!cacheFile.exists()) {
                    cacheFile.getParentFile().mkdirs();
                    cacheFile.createNewFile();
                }
                bos = new BufferedOutputStream(new FileOutputStream(localUrl));
                System.out.println("wait client ....");
                dsk.receive(dpk);
                System.out.println("wait clientq ....");
    
                int readSize = 0;
                int readCount = 0;
                int flushSize = 0;
                while ((readSize = dpk.getLength()) != 0) {
                    // validate client send exit flag
                    if (UDPUtils.isEqualsByteArray(UDPUtils.exitData, buf, readSize)) {
                        System.out.println("server exit ...");
                        // send exit flag
                        dpk.setData(UDPUtils.exitData, 0, UDPUtils.exitData.length);
                        dsk.send(dpk);
                        break;
                    }
    
                    bos.write(buf, 0, readSize);
                    if (++flushSize % 1000 == 0) {
                        flushSize = 0;
                        bos.flush();
                    }
                    dpk.setData(UDPUtils.successData, 0, UDPUtils.successData.length);
                    dsk.send(dpk);
    
                    dpk.setData(buf, 0, buf.length);
                    System.out.println("receive count of " + (++readCount) + " !");
                    dsk.receive(dpk);
                }
    
                // last flush
                bos.flush();
    
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    if (bos != null)
                        bos.close();
                    if (dsk != null)
                        dsk.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
    
    
        }
    
    }
    
    

    相关文章

      网友评论

      本文标题:羊皮书APP(Android版)开发系列(十二)Android

      本文链接:https://www.haomeiwen.com/subject/vforlttx.html