zoukankan      html  css  js  c++  java
  • Java socket 以byte[]简单分片传送数据("UTF-8"编码)

    我们选用的流是DataOutputStream和DataInputStream,下次再详解java中的各种流的区别。

    1.我们先创建对象:

    1     private DataOutputStream outputStream = null;
    2     private DataInputStream inputStream = null;

    2.然后可在构造方法中使用传入的socket对刚创建的对象定义:

     1     public ClientHandleThread(Socket socket) {
     2         this.socket = socket;
     3         this.initTimer();
     4         try {
     5             // socket.setSoTimeout(10000);
     6 //            writer = new BufferedWriter(new OutputStreamWriter(
     7 //                    this.socket.getOutputStream(), "UTF-8"));
     8 //            reader = new BufferedReader(new InputStreamReader(
     9 //                    this.socket.getInputStream(), "UTF-8"));
    10             
    11             outputStream = new DataOutputStream(this.socket.getOutputStream());
    12             inputStream = new DataInputStream(this.socket.getInputStream());
    13             
    14 
    15         } catch (Exception e) {
    16             e.printStackTrace();
    17             LogUtil.ERROR(e.getMessage());
    18         }
    19     }

    3.发送方法定义:

    简单的分片格式为:

      定义一个byte数组  byte[] buffer = new byte[1024];

      该数据中第一个byte作为分片定义格式存储:

                     /**
                      * 00000000
                      * 最高位代表是否是第一个分片,为‘1’代表是第一个分片
                      * 次高位代表是否是最后一个分片,为‘1’代表为最后一个分片
                      */
                     buffer[0] |= 0X80;//表示是第一个分片
              buffer[0] |= 0X40;//表示是最后一个分片
    当然,还可以依据需要加上具体的定义,可以参考网络协议的报头进行设计,有需要可以查看《计算机网络》一书。

    该方法分为三种走向:

      当数据byte数组bytes的大小->   0<bytes.length<=1023 时:不用分片,直接定义该片为最后一片buffer[0] |= 0X40;//表示是最后一个分片,直接发送

      当数据byte数组bytes的大小->   1023<bytes.length<=2046时,需要分为两片

      当数据byte数组bytes的大小->   2046<bytes.length时,首先要切出首片(1023大小),然后依据while(remainSize>bufferSize)循环切出中间片,最后剩下的数据量大小<=1023,这作为最后一个分片。

    具体的可以参考下列代码:

     1     // 发送
     2     public void send(String data) {
     3         try {
     4             //需要设置"UTF-8"编码,避免中文造成的乱码        
     5             byte[] bytes = (data + "
    ").getBytes("UTF-8");
     6             int posotion = 0;
     7             int remainSize = bytes.length;//剩余数据量大小
     8             int bufferSize = 1023;//缓冲区数据量大小+1
     9             if(remainSize > bufferSize)
    10             {
    11                 remainSize -=bufferSize;
    12                 byte[] buffer = new byte[1024];
    13                 buffer[0] = 0;//初始化
    14                 /**
    15                  * 00000000
    16                  * 最高位代表是否是第一个分片,为‘1’代表是第一个分片
    17                  * 次高位代表是否是最后一个分片,为‘1’代表为最后一个分片
    18                  */
    19                 buffer[0] |= 0X80;//表示是第一个分片
    20                 System.arraycopy(bytes, posotion, buffer, 1, bufferSize);    
    21                 posotion += bufferSize;
    22                 this.outputStream.write(buffer);
    23                 this.outputStream.flush();
    24                 
    25             }
    26             while (remainSize>bufferSize) {
    27                 remainSize -= bufferSize;
    28                 byte[] buffer = new byte[1024];
    29                 buffer[0] = 0;//初始化
    30 //                buffer[0] |= 0X80;//表示是第一个分片
    31 //                buffer[0] |= 0X40;//表示是最后一个分片
    32                 System.arraycopy(bytes, posotion, buffer, 1, bufferSize);
    33                 posotion += bufferSize;
    34                 this.outputStream.write(buffer);
    35                 this.outputStream.flush();
    36                 
    37             }
    38             if(remainSize > 0)
    39             {
    40                 byte[] buffer = new byte[remainSize+1];
    41                 buffer[0] = 0;//初始化
    42 //                buffer[0] |= 0X80;//表示是第一个分片
    43                 buffer[0] |= 0X40;//表示是最后一个分片
    44                 System.arraycopy(bytes, posotion, buffer, 1, remainSize);
    45                 this.outputStream.write(buffer);
    46                 this.outputStream.flush();
    47             }
    48             
    49 //            this.writer.write(data + "
    ");
    50 //            this.writer.flush();
    51             System.out.println("发送"+data);
    52         } catch (IOException e) {
    53             LogUtil.ERROR(e.getMessage());
    54             e.printStackTrace();
    55         }
    56 
    57     }

    4.下面是接收处理代码:

    需要表达的一点是,socket会依据切片的顺序发送,一般不会造成切片的顺序颠倒,当然严谨一些更好,最好增加数据包的序列号和编号。

    下面只是一个简单示例:

     1             try {
     2                 // System.out.println(RunFlag);
     3 
     4                 //char chars[] = new char[1024];
     5                 byte bytes[] = new byte[1024];
     6                 int len = 0;
     7                 StringBuilder jsonBuffer = new StringBuilder();
     8                 String temp = null;
     9                 int index = 0;
    10 //                while ((len = reader.read(chars)) != -1) {
    11 //                    temp = new String(chars, 0, len);
    12 //                    if ((index = temp.indexOf("
    ")) != -1) {// 遇到
    时就结束接收
    13 //                        jsonBuffer.append(temp.substring(0, index));
    14 //                        break;
    15 //                    }
    16 //                    jsonBuffer.append(temp);
    17 //                }
    18                 
    19                 
    20                 while ((len = inputStream.read(bytes)) != -1) {
    21                     temp = new String(bytes, 1, len-1,"UTF-8");
    22                     if ((index = temp.indexOf("
    ")) != -1 && (bytes[0] &= 0X40)==0X40) {// 遇到
    时就结束接收和最后一个分片
    23                         jsonBuffer.append(temp.substring(0, index));
    24                         break;
    25                     }
    26                     jsonBuffer.append(temp);
    27                 }
    28                 
    29 
    30                 String jsonString = jsonBuffer.toString();
    31 
                ......

    32 } catch (Exception e) { 33 LogUtil.ERROR(e.toString()); 34 }

    这里只是简单的判断一下是否为最后一个分片,可以在此基础上加上更严谨的判断。

    谢谢您的阅读,希望对您有些帮助。

  • 相关阅读:
    SpringBoot插件——EasyCode的使用(以MySQL为例)
    Springboot整合mybaties
    linux破解navicat for mysql
    springboot整合thymeleaf——引用静态资源
    整合thymeleaf
    Error: errCode: -404011 cloud function execution error | errMsg: clou……错误
    JqueryMobile与php跳转问题
    Hbuilder环境下配置php
    Bean的三种实例化方式
    利用TFTP命令上传下载H3C交换机配置文件
  • 原文地址:https://www.cnblogs.com/ning1121/p/3932165.html
Copyright © 2011-2022 走看看