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                  * 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 + "\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 }

這里只是簡單的判斷一下是否為最后一個分片,可以在此基礎上加上更嚴謹的判斷。

謝謝您的閱讀,希望對您有些幫助。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM