• 关于linux与android传输代码tcp -传文件


    关于linux与android传输代码tcp -传文件

    感谢原作者

    Android(客户端)与Linux(服务器端)进行TCP数据通信__Programmer_的博客-CSDN博客_linux+安卓apptcp图传

    原作者提供了linux与android 通过tcp连接 的代码

    经过尝试,遇到一些bug,但最终解决,感谢作者的源代码!

    本文主要将提取出传输部分,并改造成可以传输文件的代码

    源代码(传输msg版)

    默认是服务器先启动监听,然后客户端运行,建立连接,然后客户端发什么信息,服务端接受到会显示出来,并且重新发送给客户端。已经内置到自己的应用中,很成功。

    服务端

    采用的是8080端口

    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    #define PORT 8080            //服务器端监听端口号
    #define MAX_BUFFER 1024         //数据缓冲区最大值
    
    int main()
    {
        struct sockaddr_in server_addr, client_addr;
        int server_sockfd, client_sockfd;
        int size, write_size;
        char buffer[MAX_BUFFER];
    
        if ((server_sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)    //创建Socket
        {
            perror("Socket Created Failed!\n");
            exit(1);
        }
        printf("Socket Create Success!\n");
    
        server_addr.sin_family = AF_INET;
        server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
        server_addr.sin_port = htons(PORT);
        bzero(&(server_addr.sin_zero), 8);
    
        int opt = 1;
        int res = setsockopt(server_sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));    //设置地址复用
        if (res < 0)
        {
            perror("Server reuse address failed!\n");
            exit(1);
        }
    
        if (bind(server_sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1)  //绑定本地地址
        {
            perror("Socket Bind Failed!\n");
            exit(1);
        }
        printf("Socket Bind Success!\n");
    
        if (listen(server_sockfd, 5) == -1)                 //监听
        {
            perror("Listened Failed!\n");
            exit(1);
        }
        printf("Listening ....\n");
    
        socklen_t len = sizeof(client_addr);
    
        printf("waiting connection...\n");
        if ((client_sockfd = accept(server_sockfd, (struct sockaddr *)&client_addr, &len)) == -1)  //等待客户端连接
        {
            perror("Accepted Failed!\n");
            exit(1);
        }
        printf("connection established!\n");
        printf("waiting message...\n");
    
        while (1)
        {
            memset(buffer, 0, sizeof(buffer));                             //清空数据缓冲区
    
            if ((size = read(client_sockfd, buffer, MAX_BUFFER)) == -1)    //读取客户端的数据
            {
                perror("Recv Failed!\n");
                exit(1);
            }
    
            if (size != 0)                                               
            {
                buffer[size] = '\0';
                printf("Recv msg from client: %s\n", buffer);
                if ((write_size = write(client_sockfd, buffer, MAX_BUFFER)) > 0)   //把收到的数据回发给客户端
                {
                    printf("Sent msg to client successfully!\n");
                }
    
            }
        }
    
        close(client_sockfd);   //关闭Socket
        close(server_sockfd);
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91

    编译出可执行文件

    g++ con.cpp -o server
    
    • 1

    运行

    ./server  
    
    • 1
    移动端

    TcpClientConnector.java

    package com.google.ar.core.examples.java.helloar;
    
    import android.os.Bundle;
    import android.os.Handler;
    import android.os.Looper;
    import android.os.Message;
    import android.util.Log;
    
    import java.io.BufferedWriter;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.io.OutputStreamWriter;
    import java.net.Socket;
    
    public class TcpClientConnector {
    
        private static TcpClientConnector mTcpClientConnector;
        private Socket mClient;
        private ConnectListener mListener;
        private Thread mConnectThread;
    
        public interface ConnectListener {
            void onReceiveData(String data);
        }
    
        public void setOnConnectListener(ConnectListener listener) {
            this.mListener = listener;
        }
    
        public static TcpClientConnector getInstance() {
            if (mTcpClientConnector == null)
                mTcpClientConnector = new TcpClientConnector();
            return mTcpClientConnector;
        }
    
        Handler mHandler = new Handler(Looper.getMainLooper()) {
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                switch (msg.what) {
                    case 100:
                        if (mListener != null) {
                            mListener.onReceiveData(msg.getData().getString("data"));
                        }
                        break;
                }
            }
        };
    
        public void createConnect(final String mSerIP, final int mSerPort) {
            if (mConnectThread == null) {
                mConnectThread = new Thread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            connect(mSerIP, mSerPort);
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                });
                mConnectThread.start();
            }
        }
    
        /**
         * 与服务端进行连接
         *
         * @throws IOException
         */
        private void connect(String mSerIP, int mSerPort) throws IOException {
            if (mClient == null) {
                mClient = new Socket(mSerIP, mSerPort);
            }
            InputStream inputStream = mClient.getInputStream();
            byte[] buffer = new byte[1024];
            int len = -1;
            while ((len = inputStream.read(buffer)) != -1) {
                String data = new String(buffer, 0, len);
                Message message = new Message();
                message.what = 100;
                Bundle bundle = new Bundle();
                bundle.putString("data", data);
                message.setData(bundle);
                mHandler.sendMessage(message);
            }
        }
    
        /**
         * 发送数据
         *
         * @param data 需要发送的内容
         */
        public void send(String data) throws IOException {
            if(mClient!=null)
            {
                Log.d("socket",mClient.toString());
                OutputStream outputStream = mClient.getOutputStream();
                outputStream.write(data.getBytes());
            }
        }
    
        /**
         * 断开连接
         *
         * @throws IOException
         */
        public void disconnect() throws IOException {
            if (mClient != null) {
                mClient.close();
                mClient = null;
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115

    main_activity.java

     // 连接
      private TcpClientConnector connector;
    ....
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          ....
             // 创建 连接
              
               // 尝试连接
            connector = TcpClientConnector.getInstance();   //获取connector实例
            if(true){
              //连接Tcp服务器端
              connector.createConnect("10.112.146.228",8080);   //调试使用
              connector.setOnConnectListener(new TcpClientConnector.ConnectListener() {
                @Override
                public void onReceiveData(String data) {
                  //Received Data,do somethings.
                  System.out.println(data);
                }
              });
            }else{
              try{   //断开与服务器的连接
                connector.disconnect();
              }catch(IOException e){
                e.printStackTrace();
              }
            }
        .....
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    把发送信息的函数,加到你想加的函数里。记得android7以后,tcp连接必须放在线程中

     new Thread(new Runnable(){
          @Override
          public void run() {
            try {
              
              connector.send("hello world");
    
            } catch (IOException e) {
              e.printStackTrace();
            }
          }
        }).start();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    源代码(传输文件版)

    需求:需要从服务器传输一个文件,到客户端,客户端接收到后,保存至手机中。

    服务器需要传输多个文件,客户端需要对每个文件分别命名并进行保存

    服务器首先发送启示符”START" 表明传输的开始

    然后 下一个块 发送文件名

    接下来所有的块都发送文件的块

    发送完毕后 ,发送中止符 “END”

    代表该文件的发送结束

    传输一个文件版

    tips

    android 8以后禁止往外部存储写文件,使用openFileOutput 可以

    自动在data/data/包…/files/…下自动写文件(经尝试,该方法在主线程下可以创建哦)

    OutputStream os = openFileOutput("file.txt", Activity.MODE_PRIVATE);
    String str1 = "abc";
    os.write(str1.getBytes("utf-8"));
    
    • 1
    • 2
    • 3

    tips

    bug,当服务器发送字节块,采用的是1024字节的byte数组

    比如start只会占前5位,后面全填0

    而客户端接受的会将整个字节数组转化为字符串,就变成这个样子

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3q63bnuL-1668068832148)(%E5%85%B3%E4%BA%8Elinux%E4%B8%8Eandroid%E4%BC%A0%E8%BE%93%E4%BB%A3%E7%A0%81tcp%20-%E4%BC%A0%E6%96%87%E4%BB%B6.assets/image-20221110102121564.png)]

    解决这个bug有两个方向

    一个是找到android端能够截取byte数组的函数

    感谢作者[Java中去掉byte]中填充的0,并且转为String_银龙gg的博客-CSDN博客

    但这样会有点担心,(因为平常的字节流为有0,会被提前中止)

    经过探寻 该0为彼0(实际上传递的是0的assci码 48)

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HF6EAdki-1668068832149)(%E5%85%B3%E4%BA%8Elinux%E4%B8%8Eandroid%E4%BC%A0%E8%BE%93%E4%BB%A3%E7%A0%81tcp%20-%E4%BC%A0%E6%96%87%E4%BB%B6.assets/image-20221110104956116.png)]

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-m09BDfRH-1668068832150)(%E5%85%B3%E4%BA%8Elinux%E4%B8%8Eandroid%E4%BC%A0%E8%BE%93%E4%BB%A3%E7%A0%81tcp%20-%E4%BC%A0%E6%96%87%E4%BB%B6.assets/image-20221110105506360.png)]

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4EBQI8db-1668068832150)(%E5%85%B3%E4%BA%8Elinux%E4%B8%8Eandroid%E4%BC%A0%E8%BE%93%E4%BB%A3%E7%A0%81tcp%20-%E4%BC%A0%E6%96%87%E4%BB%B6.assets/image-20221110105515496.png)]

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-srDbWKnt-1668068832151)(%E5%85%B3%E4%BA%8Elinux%E4%B8%8Eandroid%E4%BC%A0%E8%BE%93%E4%BB%A3%E7%A0%81tcp%20-%E4%BC%A0%E6%96%87%E4%BB%B6.assets/image-20221110105555830.png)]

    而ascci码为0的是字符null,根本不需要有这方面的担心(后续还是有bug)

    /指定长度100
    private byte[] bytes = new byte[100];
    
    //此处省略获取数据  byte[]中的数据实际长度为30   剩余的70将会自动填充0
    //直接转为String
    String str = new String(bytes);
    //str中前30位为正常字符  后70位为填充  直接页面展示会乱码
    System.out.print(str);
    //通过下面的方法去掉自动填充的0
    String str1 = StringUtils.byteToStr(bytes);
    System.out.print(str1); //正确数据 只有实际的30位  没有填充的乱码
    
     /**
         * 去掉byte[]中填充的0 转为String
         * @param buffer
         * @return
         */
        public static String byteToStr(byte[] buffer) {
            try {
                int length = 0;
                for (int i = 0; i < buffer.length; ++i) {
                    if (buffer[i] == 0) {
                        length = i;
                        break;
                    }
                }
                return new String(buffer, 0, length, "UTF-8");
            } catch (Exception e) {
                return "";
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    一个是增加服务端与客户端发送的逻辑(比如也发送字长,或者为每个块添加中止符什么的)

    前面方法已经可以了,因此放弃该思路

    bug1

    把发送文件块的全部截取成0了…

    通过增加逻辑,对于文件名,启示符,结束符进行截取

    对于文件块进行不截取的方式,解决问题。

    bug2

    按说应该传完start和文件名,再传文件块

    文件块传完毕后,会传送最后一个文件块,以END开头

    但不知为什么,END的块,与最后一个文件包混到了一起

    发送完文件块后,等待1s

    服务端代码
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include
    #include
    
    
    #define PORT 8080            //服务器端监听端口号
    #define MAX_BUFFER 1024         //数据缓冲区最大值
    using namespace std;
    int main()
    {
        struct sockaddr_in server_addr, client_addr;
        int server_sockfd, client_sockfd;
        int size, write_size;
        char buffer[MAX_BUFFER];
    
        if ((server_sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)    //创建Socket
        {
            perror("Socket Created Failed!\n");
            exit(1);
        }
        printf("Socket Create Success!\n");
    
        server_addr.sin_family = AF_INET;
        server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
        server_addr.sin_port = htons(PORT);
        bzero(&(server_addr.sin_zero), 8);
    
        int opt = 1;
        int res = setsockopt(server_sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));    //设置地址复用
        if (res < 0)
        {
            perror("Server reuse address failed!\n");
            exit(1);
        }
    
        if (bind(server_sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1)  //绑定本地地址
        {
            perror("Socket Bind Failed!\n");
            exit(1);
        }
        printf("Socket Bind Success!\n");
    
        if (listen(server_sockfd, 5) == -1)                 //监听
        {
            perror("Listened Failed!\n");
            exit(1);
        }
        printf("Listening ....\n");
    
        socklen_t len = sizeof(client_addr);
    
        printf("waiting connection...\n");
        if ((client_sockfd = accept(server_sockfd, (struct sockaddr *)&client_addr, &len)) == -1)  //等待客户端连接
        {
            perror("Accepted Failed!\n");
            exit(1);
        }
        printf("connection established!\n");
    
        // 开始传文件
        //发送一个文件名
        //bytes[]
    
        
        string start="START";
        char buf[1024] = { 0 };
        strcpy(buf, start.c_str());
        write(client_sockfd,buf,MAX_BUFFER);
        memset(buf, 0, sizeof(buf)); 
    
    
        string name ="1.txt";
        strcpy(buf, name.c_str());
        write(client_sockfd,buf,MAX_BUFFER);
        memset(buf, 0, sizeof(buf)); 
        int bytes;
        FILE* fp = fopen("test1.txt", "rb");
    
        while ((bytes = fread(buf, 1, 1024, fp) )> 0)//读取文件内容,每次一个1024字节
        {
            cout<<bytes<<endl;
            // for(auto byte:buf)
            // {
            //     cout<
            // }
            // cout<
            write(client_sockfd,buf,MAX_BUFFER);//把buf里存的东西send给服务端
            memset(buf, 0, sizeof(buf)); 
        }
    
        sleep(1);
        string end="END";
        strcpy(buf, end.c_str());
        for(auto byte:buf)
            {
                cout<<byte<<" ";
            }
            cout<<endl;
        write(client_sockfd,buf,MAX_BUFFER);
        memset(buf, 0, sizeof(buf)); 
        
    
    
        // printf("waiting message...\n");
    
        // while (1)
        // {
        //     memset(buffer, 0, sizeof(buffer));                             //清空数据缓冲区
    
        //     if ((size = read(client_sockfd, buffer, MAX_BUFFER)) == -1)    //读取客户端的数据
        //     {
        //         perror("Recv Failed!\n");
        //         exit(1);
        //     }
    
        //     if (size != 0)                                               
        //     {
        //         buffer[size] = '\0';
        //         printf("Recv msg from client: %s\n", buffer);
        //         if ((write_size = write(client_sockfd, buffer, MAX_BUFFER)) > 0)   //把收到的数据回发给客户端
        //         {
        //             printf("Sent msg to client successfully!\n");
        //         }
        //     }
        // }
    
        close(client_sockfd);   //关闭Socket
        close(server_sockfd);
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    客户端代码

    on create中创建连接

     // 尝试连接
        connector = TcpClientConnector.getInstance();   //获取connector实例
        if(true){
          //连接Tcp服务器端
          connector.createConnect("10.112.146.228",8080);   //调试使用
          connector.setOnConnectListener(new TcpClientConnector.ConnectListener() {
            @Override
            public void onReceiveData(String data) {
    
              //Received Data,do somethings.
              Log.i("received", String.valueOf(data.length()));
              Log.i("received",data);
    
    
              if(receive_state==0 && data.equals("START")) //准备接受文件名
              {
                Log.i("file1","文件传输开始,准备接受文件名噢");
                os = null;
                receive_state=1;
              }
              else if (receive_state==1)//接受文件名
              {
    
                file_name=byteToStr(data.getBytes());
                Log.i("file1","接受到文件名:"+file_name);
                try {
                  os = openFileOutput(file_name, Context.MODE_PRIVATE);
                } catch (IOException e) {
                  e.printStackTrace();
                }
                receive_state=2;
              }
              else if(receive_state==2 && !data.equals("END") && data.length()!=0) //接受文件块
              {
                Log.i("file1","正在写入块:"+data.getBytes().length);
                try {
                  os.write(data.getBytes());
                } catch (IOException e) {
                  e.printStackTrace();
                }
              }
              else if(data.equals("END")) //该文件传输结束
              {
                Log.i("file1","文件写入结束");
                try {
                  os.close();
                } catch (IOException e) {
                  e.printStackTrace();
                }
                os=null;
                receive_state=0;
                file_name=null;
              }
            }
          });
        }else{
          try{   //断开与服务器的连接
            connector.disconnect();
          }catch(IOException e){
            e.printStackTrace();
          }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62

    截取函数

     public String byteToStr(byte[] buffer) {
        try {
          int length = 0;
          for (int i = 0; i < buffer.length; ++i) {
            if (buffer[i] == 0) {
              length = i;
              break;
            }
          }
          return new String(buffer, 0, length, "UTF-8");
        } catch (Exception e) {
          return "";
        }
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    TcpClientConnector

    package com.google.ar.core.examples.java.helloar;
    
    import android.content.Context;
    import android.os.Bundle;
    import android.os.Handler;
    import android.os.Looper;
    import android.os.Message;
    import android.util.Log;
    
    
    import java.io.BufferedOutputStream;
    import java.io.BufferedWriter;
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.io.OutputStreamWriter;
    import java.net.Socket;
    
    
    public class TcpClientConnector {
    
        private static TcpClientConnector mTcpClientConnector;
        private Socket mClient;
        private ConnectListener mListener;
        private Thread mConnectThread;
        private BufferedOutputStream bos= null;
    
        public interface ConnectListener {
            void onReceiveData(String data);
        }
    
        public void setOnConnectListener(ConnectListener listener) {
            this.mListener = listener;
        }
    
        public static TcpClientConnector getInstance() {
            if (mTcpClientConnector == null)
                mTcpClientConnector = new TcpClientConnector();
            return mTcpClientConnector;
        }
    
        Handler mHandler = new Handler(Looper.getMainLooper()) {
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                switch (msg.what) {
                    case 100:
                        if (mListener != null) {
                            mListener.onReceiveData(msg.getData().getString("data"));
                        }
                        break;
                }
            }
        };
    
        public void createConnect(final String mSerIP, final int mSerPort) {
            if (mConnectThread == null) {
                mConnectThread = new Thread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            connect(mSerIP, mSerPort);
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                });
                mConnectThread.start();
            }
        }
        /**
         * 去掉byte[]中填充的0 转为String
         * @param buffer
         * @return
         */
        public static String byteToStr(byte[] buffer) {
            try {
                int length = 0;
                for (int i = 0; i < buffer.length; ++i) {
                    if (buffer[i] == 0) {
                        length = i;
                        break;
                    }
                }
                return new String(buffer, 0, length, "UTF-8");
            } catch (Exception e) {
                return "";
            }
        }
        /**
         * 与服务端进行连接
         *
         * @throws IOException
         */
        private void connect(String mSerIP, int mSerPort) throws IOException {
            if (mClient == null) {
                mClient = new Socket(mSerIP, mSerPort);
            }
            InputStream inputStream = mClient.getInputStream();
            byte[] buffer = new byte[1024];
            int len = -1;
    
    
            while ((len = inputStream.read(buffer)) != -1) {
    //            String data = new String(buffer, 0, len);
                Log.i("real_string", String.valueOf(len));//len_byte能看出接受到的块大小
                String real_data=new String(buffer,0,len);
    
                // 如果是start,end 就放截取后的
                // 其他 放未截取的 文件名则主线程截取
                String data =byteToStr(buffer);
                Message message = new Message();
                message.what = 100;
                Bundle bundle = new Bundle();
                Log.i("real_string","一块:");
                Log.i("real_string",real_data);//real_string表明实际接收到的数据
                if (data.equals("START") || data.equals("END"))
                {
                    bundle.putString("data", data);
                }
                else
                {
                    bundle.putString("data", real_data);
                }
                message.setData(bundle);
                mHandler.sendMessage(message);
            }
            if (bos!=null){
                bos.close();
            }
    
        }
    
        /**
         * 发送数据
         *
         * @param data 需要发送的内容
         */
        public void send(String data) throws IOException {
            if(mClient!=null)
            {
                Log.d("socket",mClient.toString());
                OutputStream outputStream = mClient.getOutputStream();
                outputStream.write(data.getBytes());
            }
        }
    
        /**
         * 断开连接
         *
         * @throws IOException
         */
        public void disconnect() throws IOException {
    
            if (mClient != null) {
                mClient.close();
                mClient = null;
            }
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    传输多个文件版
  • 相关阅读:
    十五、红外遥控器
    牛客模拟面 面经1/2
    [要素察觉]C语言七讲:结构体及C++引用讲解
    03.模块一 前端基础html、css、js
    按键精灵打怪学习-前台和内网发送后台验证码
    Windows搭建青龙面板并且可以外网登录教程
    单商户商城系统功能拆解16—供应商管理
    添加阿里云maven镜像
    Java Date类简介说明
    参加霍格沃兹测试开发学社举办的火焰杯软件测试开发大赛是一种什么体验?
  • 原文地址:https://blog.csdn.net/hch977/article/details/127791489