Android 实现只创建一个socket就能一次传输多个文件

来源:互联网 发布:罗技g502 mac 编辑:程序博客网 时间:2024/05/16 18:24

Android 实现一个socket传输多个文件

在网上看到好多关于socket的文章都是创建一次socket只传输一个文件,这种方式如果在需要一次传多文件的情况下,要创建很多个socket,显然这样的效率是不好的,所以我写了一个socket一次传多个文件的demo,没code说个屌,代码如下:

1.server socket

public class RespMultiFileListThread extends Thread {    private static final String TAG = "RespMultiFileListThread";    public boolean mIsRunThread = true;    private DataInputStream in;    private DataOutputStream out;    Socket client;    private Intent mIntent;    private Context mContext;    private DeviceBean mDeviceBean;    public RespMultiFileListThread(Context context, Socket client) {        this.mContext = context;        this.client=client;        this.start();        initDeviceData();    }    public void run() {        File file ;        byte[] fileTempBytes = new byte[1024];        int len = -2;        FileInputStream fis;        String rawCmd = "";        try {            in = new DataInputStream(client.getInputStream());            out = new DataOutputStream(client.getOutputStream());            rawCmd = in.readUTF();        } catch (IOException e1) {            e1.printStackTrace();        }        //获取请求命令        if(! rawCmd.equals("req_thumb_list")){            try {                in.close();                out.close();                client.close();            } catch (IOException e) {            }            return;        }        //返回设备文件信息        try {            out.writeUTF(new Gson().toJson(mDeviceBean));        } catch (IOException e1) {            e1.printStackTrace();        }        if(mDeviceBean == null ){            return ;        }        HashMap<String , Long> thumbMap = mDeviceBean.getFileMap();        if(thumbMap == null ||thumbMap.size() == 0){            try {                in.close();                out.close();                client.close();            } catch (IOException e) {            }            return;        }        Set set = thumbMap.entrySet() ;        Iterator it = thumbMap.entrySet().iterator();        Entry entry;        while (it.hasNext()) {            entry = (Entry) it.next();            try {                String fileName = in.readUTF();                Log.i(TAG, fileName);                file = new File(MyApplication.mFilesPath+"/" + fileName);                fis = new FileInputStream(file);                while ((len = fis.read(fileTempBytes, 0, fileTempBytes.length)) != -1) {                    out.write(fileTempBytes, 0, len);                      out.flush();                  }                if(len == -1){                    Log.i(TAG, "send completed");                }            } catch (IOException e) {                Log.i(TAG, e.toString());                e.printStackTrace();                Log.i(TAG, "客户端已下线,结束本次");            }        }        try {            client.close();        } catch (IOException e) {        }    }    private void initDeviceData(){        mDeviceBean = new DeviceBean();        mDeviceBean.setDeviceName(Build.MANUFACTURER +" " + Build.MODEL);        mDeviceBean.setDeviceType("android");        mDeviceBean.setMacAddr(PhoneInfoUtils.getMacAddr(mContext));        mDeviceBean.setLanGroupId(MyApplication.mLanGroupId);        //TODO thumb path        HashMap<String, Long> fileMap = FileUtils.getFileMap(MyApplication.mFilesPath);        mDeviceBean.setFileMap(fileMap);        mDeviceBean.setIpAddr(NetWorkUtils.getWifiIp(mContext));    }

2.client socket

 public ReqMultiFileClientThread(Context context, Handler handler, String ip , int port ,String formMac) {        this.mHandler = handler;        this.mFromDeviceMac = formMac;        this.mIp = ip;        this.mPort = 1241;    }    private void connectServer(String ip, int port) {        if (!mIsFirstCreate) {            mHandler.sendEmptyMessage(MSG_TRYING_CONNECT);        }        try {            if(!mIsCanConnect || !mIsSetReConnect){                return;            }            Log.i(TAG, "正在尝试连接服务器...");            mIsCanConnect = false;            mClient = new Socket();            mClient.connect(new InetSocketAddress(ip, port), TIME_OUT_CONNECT);            mClient.setSoTimeout(TIME_OUT_READ_DATA);            Log.i(TAG, "连接服务器成功:" + ip + "   " + port);            in = new DataInputStream(mClient.getInputStream());            out = new DataOutputStream(mClient.getOutputStream());            mIsRunThread = true;            if (mIsFirstCreate) {                mIsFirstCreate = false;            } else {                this.run();            }            mHandler.sendEmptyMessage(MSG_CONNECT_OK);        } catch (IOException e) {            mIsCanConnect = true;            mHandler.sendEmptyMessage(MSG_CONNECT_FAILD);            Log.i(TAG, "连接服务器失败:" + ip + "   " + port);            try {                sleep(3*1000);            } catch (InterruptedException e1) {                e1.printStackTrace();            }            connectServer(mIp, mPort);        }    }    public void run() {        connectServer(mIp, mPort);        Log.i(TAG, "ReqMultiFileClientThread running");        File saveFolder = new File(MyApplication.mReceiveFolder+"/"+mFromDeviceMac);        if(!saveFolder.exists()){            saveFolder.mkdirs();        }        byte[] fileTempBytes = new byte[1024];        FileOutputStream mFileOutputStream;        Message mMessage ;        Log.i(TAG, "发送thumb请求cmd给服务器请求下载...");        String thumbListStr;        try {            out.writeUTF("req_thumb_list");            thumbListStr = in.readUTF();        } catch (IOException e1) {            e1.printStackTrace();            try {                out.close();                in.close();            } catch (IOException e) {            }            return;        }        if(StrUtils.isEnpty(thumbListStr)){            return ;        }        DeviceBean reqDeviceBean;        try{            reqDeviceBean = new Gson().fromJson(thumbListStr, DeviceBean.class);        } catch(JsonSyntaxException e){            e.printStackTrace();            return;        }        if(reqDeviceBean == null){            return;        }        HashMap<String, Long> thumbMap = reqDeviceBean.getFileMap();        //一个文件都没有        if(thumbMap == null || thumbMap.size() == 0){            return;        }        Set set = thumbMap.entrySet() ;        Iterator it = thumbMap.entrySet().iterator();        while (it.hasNext()) {            Entry entry = (Entry) it.next();            File saveFile = new File(saveFolder.getAbsolutePath() + "/" + entry.getKey());            String mFileName = entry.getKey()+"";            mFileLength = (long) entry.getValue();            float sum = 0;            int len = -2;            try {                mFileOutputStream = new FileOutputStream(saveFile);                try{                    out.writeUTF(entry.getKey()+"");                    while ((len = in.read(fileTempBytes, 0, fileTempBytes.length)) != -1) {                        mFileOutputStream.write(fileTempBytes, 0, len);                        mFileOutputStream.flush();                        sum += len;                        Log.i(TAG, sum/mFileLength * 100+"%");                        mHandler.sendEmptyMessage((int) (sum/mFileLength * 100));                        if(sum == mFileLength){                            break;                        }                    }                } catch(SocketTimeoutException e){   //服务器断开导致的异常                    e.printStackTrace();                    Log.i(TAG, "连接超时!");                    mIsCanConnect = true;                } catch(SocketException e){    //本地网络断开导致的异常                     e.printStackTrace();                    Log.i(TAG, "网络断开,连接超时!");                    mIsCanConnect = true;                }                Log.i(TAG, "接收完成");                mMessage = new Message();                mMessage.obj = new File(saveFolder.getAbsolutePath()+"/"+mFileName.substring(0, mFileName.length()-2));                mHandler.sendMessage(mMessage);            }catch (IOException e) {                e.printStackTrace();            }        }        mIsRunThread = false;        try {            mClient.close();        } catch (IOException e) {        }        mIsCompleted = true;    }}

通过请求一个 返回一个文件的方式,可以避免多个文件连续处出现多余或者缺少的发生,比如,设定buffer byte[] 大小为1024,但是实际上某个文件最后一个一次buffer并不刚好是1024,然后会把下一个文件的流数据混合进去,导致上一个文件多了,下一个文件少了,现在通过这种请求再返回文件数据流的方式就可以分隔开来

通过请求一次返回一个文件的方式,可以避免多个文件连续处出现多余或者缺少的发生,比如,设定buffer byte[] 大小为1024,但是实际上某个文件最后一个一次buffer并不刚好是1024,然后会把下一个文件的流数据混合进去,导致上一个文件多了,下一个文件少了,现在通过这种请求再返回文件数据流的方式就可以分隔开来

0 0
原创粉丝点击