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             }

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

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

时间: 2024-08-08 21:56:52

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

170411、java Socket通信的简单例子(UDP)

服务端代码: package com.bobohe.socket; import java.io.*; import java.net.*; class UDPServer { public static void main(String[] args) throws IOException { DatagramSocket server = new DatagramSocket(5050); byte[] recvBuf = new byte[100]; DatagramPacket recv

java socket编程开发简单例子

1.以下只是简单例子,没有用多线程处理,只能一发一收(由于scan.nextLine()线程会进入等待状态),使用时可以根据具体项目功能进行优化处理 2.以下代码使用了1.8新特性,如果要测试以下代码,java版本不能低于1.8 // 客户端 public static void main(String[] args) { try (Scanner scan = new Scanner(System.in); Socket client = new Socket("127.0.0.1"

170410、java Socket通信的简单例子(TCP)

服务端代码: package com.bobohe.socket; import java.io.*; import java.net.*; import java.applet.Applet; public class TalkServer { public static void main(String args[]) { try { ServerSocket server = null; try { server = new ServerSocket(4700); // 创建一个Serve

Java Socket发送与接收HTTP消息简单实现

在上次Java Socket现实简单的HTTP服务我 们实现了简单的HTTP服务,它可以用来模拟HTTP服务,用它可以截获HTTP请求的原始码流,让我们很清楚的了解到我们向服务发的HTTP消息的结 构,对HTTP请求消息有个清晰的认识.这一节我想写了一个客户的程序,就是用来模拟浏览器,用来向服务器发送HTTP请求,最得要的是可以用它来显示服 务器发回来的HTTP响应消息的一般结构. [java] view plaincopy import java.io.IOException; import 

Java]Socket和ServerSocket服务器端接受数据

java socket 与  ServerSocket 某次写一个智能设备上传数据,数据每次三秒一条,然后使用c++写的客户端,没有对应java的源码,只能自己手写了,期间各种问题现在总结下 首先用的框架是ssh(我想用那个应该是没什么差别),因为是添加到web项目中的,so我想到的是tomcat启动的时候启动,于是首先必须要有的是后台程序,否则tomcat无法启动成功:话不多说,上源码... web.xml中我最后选用的是listener  监听还有一种是servlet  应该都可以 我最后选

java Socket实现简单在线聊天(一)

出处:http://blog.csdn.net/tuzongxun 最近的项目有一个在线网页交流的需求,由于很久以前做过的demo已经忘记的差不多了,因此便重新学习一下. 我计划的大致实现步骤分这样几大步: 1.使用awt组件和socket实现简单的单客户端向服务端持续发送消息: 2.结合线程,实现多客户端连接服务端发送消息: 3.实现服务端转发客户端消息至所有客户端,同时在客户端显示: 4.把awt组件生成的窗口界面改成前端jsp或者html展示的界面,java socket实现的客户端改为前

我看不下去鸟。。。。Java和C#的socket通信真的简单吗?

这几天在博客园上看到好几个写Java和C#的socket通信的帖子.但是都为指出其中关键点. C# socket通信组件有很多,在vs 使用nuget搜索socket组件有很多类似的.本人使用的是自己开发的一套组件. Java socket通信的组件也有很多,常用的大多数都是用的mina或者netty.游戏行业使用也是居多. 关于socket的底层写法,实在太多,我就不在BB. 这里我想说,C#和C++或者叫VC++把是使用小端序作为字节序.而java使用的是大端序作为字节序. 也就是说比如一个

linux下java程序与C语言程序通过SOCKET通信的简单例子

linux下java程序与C语言程序通过SOCKET通信的简单例子 今天上午实验了java程序与c语言程序通过socket进行通信.由于没学过java,因此只是编写了C语言端的代码,java端的代码是从网上别的文章中找的,经过少量修改后与C语言端程序通信成功. 本例中C语言端作为服务器,java端作为客户端 代码如下: /****************** server program *****************/ #include <stdio.h> #include <sy

利用java的Socket实现一个简单hello/hi聊天程序

利用java的Socket实现一个简单hello/hi聊天程序 首先,我们来用java实现一个简单的hello/hi聊天程序.在这个程序里,我学习到了怎么用socket套接套接字来进行编程.简单理解了一些关于socket套接字和底层调用的关系.关于java的封装思想,我学会了一些东西,java里真的是万物皆对象.还学到了一点多线程的知识. TCP 在这里,不得不先介绍以下TCP.TCP是传输层面向连接的协议.提供了端到端的进程之间的通信方式.TCP在通信之前要先建立连接.这里我们称这个建立连接的