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

原创 2015年11月20日 18:51:04

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,然后会把下一个文件的流数据混合进去,导致上一个文件多了,下一个文件少了,现在通过这种请求再返回文件数据流的方式就可以分隔开来

版权声明:本文为博主原创文章,未经博主允许不得转载。

通过Socket连接一次传输多个文件

最近在做一个通过WIFI在手机之间传输文件的功能。需要在手机之间建立一个持久的Socket连接并利用该连接传输数据。可以一次传输一个或多个文件。 在一次传输多个文件时,遇到了一个困难:如何在接收文件...
  • fx1ts
  • fx1ts
  • 2014年08月20日 10:33
  • 1852

【Java小项目】一个Socket连续传输多个文件

想给前短时间做的那个山寨QQ加一个传输文件的功能,因为那个山寨QQ每个客户端和服务器端就一个Socket连接用ObjectOutputStream进行通信,现在要加一个DataOutputStream...
  • A__yes
  • A__yes
  • 2015年11月17日 18:25
  • 2342

试用socket api借口设计一个文件传送软件,并编程实现,可自定义文件传输的通信。

http://zhidao.baidu.com/question/192956443.html我用C++写的,可以调试的!要加分啊啊!记得啊!呵呵...代码如下我用C++写的,可以调试的!要加分啊啊!...
  • Open9i
  • Open9i
  • 2011年05月12日 17:23
  • 497

一次选择多个文件实现上传功能

  • 2013年05月20日 14:16
  • 3.71MB
  • 下载

Android Socket 聊天工具(一个服务端实现多个客户端间通信)

程序开源,共同学习。最近在学Android,做了一个由Socket实现的基于TCP协议的聊天工具,用一个服务端支持多个客户端之间的交流 通信。虽然本人之前做过蓝牙控制小车的软件,但这次做起来也花了不少...

Android Socket 聊天工具(一个服务端实现多个客户端间通信)

程序开源,共同学习。最近在学Android,做了一个由Socket实现的基于TCP协议的聊天工具,用一个服务端支持多个客户端之间的交流 通信。虽然本人之前做过蓝牙控制小车的软件,但这次做起来也花了不少...

java socket 多线程网络传输多个文件

由于需要研究了下用 java socket 传输文件,由于需要传输多个文件,因此,采用了多线程设计。客户端每个线程创建一个 socket 连接,每个 socket 连接负责传输一个文件,服务端的Ser...

java socket多线程网络传输多个文件

由于需要研究了下用java socket传输文件,由于需要传输多个文件,因此,采用了多线程设计。客户端每个线程创建一个socket连接,每个socket连接负责传输一个文件,服务端的ServerSoc...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Android 实现只创建一个socket就能一次传输多个文件
举报原因:
原因补充:

(最多只允许输入30个字)