首页 > 代码库 > Java socket 以byte[]简单分片传送数据("UTF-8"编码)

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 + "\r\n").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                  * 0000000016                  * 最高位代表是否是第一个分片,为‘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 + "\r\n");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("\n")) != -1) {// 遇到\n时就结束接收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("\n")) != -1 && (bytes[0] &= 0X40)==0X40) {// 遇到\n时就结束接收和最后一个分片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 }

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

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

 

Java socket 以byte[]简单分片传送数据("UTF-8"编码)