socket网络通信 protobuffer序列化

什么是socket网络通信

参考:https://blog.csdn.net/u014209205/article/details/80461122

TCP/UDP

进行Socket编程, 常见使用的协议UDP/TCP
TCP:传输控制协议 。是专门设计用于在不可靠的因特网上提供可靠的,端到端的字节流通信的协议。它是一种面向连接的协议。TCP连接是字节流而非报文流。
UDP:用户数据报协议 。不需要建立连接,不可靠。

socket网络通信 protobuffer序列化_第1张图片
socket网络通信 protobuffer序列化_第2张图片

消息数据类型

  • Json交换格式, 目前比较理想的一种通信格式, 也是在Http请求数据时, 最常见的用法(Demo程序)
  • ProtocolBuffer(也称PB/GPB): google 的一种数据交换的格式, 可以实现跨平台, 方便的序列化&反序列化, 并且数据量相对json

ProtocolBuffer
1、简介

  • 跨平台
    ProtoBuf支持多平台和语言, 包括C++/Java/Python等等
    序列化&反序列号
  • ProtoBuf支持直接将对象序列化成Data, 也支持直接将Data序列化为对象类型
    消息大小
  • 一条消息数据,用protobuf序列化后的大小是json的10分之一,xml格式的20分之一,是二进制序列化的10分之一
    2、安装Protobuf编译器

参照:https://www.jianshu.com/p/cae40f8faf1e

传输的是一句话时候

ServerThread.java

package demo2;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;

import java.io.*;
import java.net.Socket;
import java.util.Arrays;

public class ServerThread extends Thread {


    private Socket socket = null;

    public ServerThread(Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run() {
        InputStream is=null;
        InputStreamReader isr=null;
        BufferedReader br=null;
        OutputStream os=null;
        PrintWriter pw=null;
        try {
            is = socket.getInputStream();//字节输入流 读入
            isr = new InputStreamReader(is);//转为字符流
            br = new BufferedReader(isr);//放入缓存等待读取

            String info = null;

            while((info=br.readLine())!=null){
                System.out.println("我是服务器,客户端说:"+info);
            }
            socket.shutdownInput();

            os = socket.getOutputStream();
            pw = new PrintWriter(os);
            pw.write("服务器欢迎你");

            pw.flush();
        } catch (Exception e) {
            // TODO: handle exception
        } finally{
            //关闭资源
            try {
                if(pw!=null)
                    pw.close();
                if(os!=null)
                    os.close();
                if(br!=null)
                    br.close();
                if(isr!=null)
                    isr.close();
                if(is!=null)
                    is.close();
                if(socket!=null)
                    socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    }




SocketClient.java

package demo2;

import com.alibaba.fastjson.JSON;

import java.io.*;
import java.net.Socket;
import java.util.Arrays;

public class SocketClient {



    public static void main(String[] args) throws InterruptedException {
        try {
            // 和服务器创建连接
            Socket socket = new Socket("localhost",8099);
            Person person = new Person();
            person.setAge(18);
            person.setHeight(19);
            person.setId(1);
            String str = JSON.toJSONString(person);
            byte[] bytes = str.getBytes();

            // 要发送给服务器的信息
            OutputStream os = socket.getOutputStream();
            os.write(bytes);//写出到服务器

            PrintWriter pw = new PrintWriter(os);
            pw.write("客户端发送信息");
            pw.flush();

            socket.shutdownOutput();

            // 从服务器接收的信息
            InputStream is = socket.getInputStream();
//            BufferedReader br = new BufferedReader(new InputStreamReader(is));
//            String info = null;
//            while((info = br.readLine())!=null){
//                System.out.println("我是客户端,服务器返回信息:"+info);
//            }
            byte[] bytes1 = new byte[1024];

            int read = is.read(bytes1);
            byte[] bytes2 = Arrays.copyOfRange(bytes1, 0, read);
            String s = new String(bytes2);
            System.out.println(s);

            // br.close();
            is.close();
            os.close();
            pw.close();
            socket.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    }


SocketServer.java

package demo2;

import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;

public class SocketServer {
    public static void main(String[] args) {
        try {
            // 创建服务端socket
            ServerSocket serverSocket = new ServerSocket(8088);

            // 创建客户端socket
            Socket socket = new Socket();

            //循环监听等待客户端的连接
            while(true){
                // 监听客户端
                socket = serverSocket.accept();

                ServerThread thread = new ServerThread(socket);
                thread.start();

                InetAddress address=socket.getInetAddress();
                System.out.println("当前客户端的IP:"+address.getHostAddress());
            }
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }
    }


}

传输是一个对象的时候(以json格式传输)

Person.java

package demo3;

public class Person {
    int id;
    int height;
    int age;

    @Override
    public String toString() {
        return "Person{" +
                "id=" + id +
                ", height=" + height +
                ", age=" + age +
                '}';
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public int getHeight() {
        return height;
    }

    public void setHeight(int height) {
        this.height = height;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

ServerThread.java

package demo3;

import java.io.*;
import java.net.Socket;
import java.util.Arrays;

public class ServerThread extends Thread {


    private Socket socket = null;

    public ServerThread(Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run() {
        InputStream is=null;
//        InputStreamReader isr=null;
//        BufferedReader br=null;
        OutputStream os=null;
        PrintWriter pw=null;
        byte[] bytes2=null;
        String s1=null;
        try {

            is = socket.getInputStream();
//            isr = new InputStreamReader(is);
//            br = new BufferedReader(isr);
            byte[] bytes = new byte[1024];
            int read = is.read(bytes);

            if (read > 0) {

                bytes2 = Arrays.copyOfRange(bytes, 0, read);
                s1 = new String(bytes2);//byte转字符串
            }

                System.out.println("我是服务器,客户端说:"+s1);

            socket.shutdownInput();

            os = socket.getOutputStream();
            pw = new PrintWriter(os);
            pw.write("服务器欢迎你");

            pw.flush();
        } catch (Exception e) {
            // TODO: handle exception
        } finally{
            //关闭资源
            try {
                if(pw!=null)
                    pw.close();
                if(os!=null)
                    os.close();
//                if(br!=null)
//                    br.close();
//                if(isr!=null)
//                    isr.close();
                if(is!=null)
                    is.close();
                if(socket!=null)
                    socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    }




SocketClient.java

package demo3;

import com.alibaba.fastjson.JSON;

import java.io.*;
import java.net.Socket;

public class SocketClient {
    public static void main(String[] args) throws InterruptedException {
        try {
            // 和服务器创建连接
            Socket socket = new Socket("localhost", 8084);

            // 要发送给服务器的信息
            OutputStream os = socket.getOutputStream();

            // ####使用的对象转json,json字符串,转bytes数组方式,传输字节流
            Person person = new Person();//创建一个对象
            person.setAge(10);
            person.setHeight(100);

            String s = JSON.toJSONString(person); //对象转json字符串
            byte[] bytes = s.getBytes(); //字符串转bytes数组
            os.write(bytes); //socket写出到服务器
            PrintWriter pw = new PrintWriter(os);
            pw.write("客户端发送信息");
            pw.flush();
            os.flush();
            socket.shutdownOutput();

            // 从服务器接收的信息
            InputStream is = socket.getInputStream();
            BufferedReader br = new BufferedReader(new InputStreamReader(is));
            String info = null;
            while ((info = br.readLine()) != null) {
                System.out.println("我是客户端,服务器返回信息:" + info);
            }

            br.close();
            is.close();
            os.close();
            pw.close();
            socket.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}



SocketServer.java

package demo3;

import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;

public class SocketServer {
    public static void main(String[] args) {
        try {
            // 创建服务端socket
            ServerSocket serverSocket = new ServerSocket(8084);

            // 创建客户端socket
            Socket socket = new Socket();

            //循环监听等待客户端的连接
            while(true){
                // 监听客户端
                socket = serverSocket.accept();

                ServerThread thread = new ServerThread(socket);
                thread.start();

                InetAddress address=socket.getInetAddress();
                System.out.println("当前客户端的IP:"+address.getHostAddress());
            }
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }
    }


}

使用protobuffer序列化后传输

Person.proto

syntax = "proto3";
option java_package = "demo";//生成类的包名
option  java_outer_classname = "PersonTest";//生成类的类名

message person{
  repeated int32 id     = 1;
  string         name   = 2;
  int32          height = 3;
  string         email  = 4;
}

ServerThread.java

import demo.PersonTest;

import java.io.*;
import java.net.Socket;
import java.util.Arrays;

public class ServerThread extends Thread {


    private Socket socket = null;

    public ServerThread(Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run() {
        InputStream is = null;
        InputStreamReader isr = null;
        BufferedReader br = null;
        OutputStream os = null;
        PrintWriter pw = null;
        String s1 = null;
        byte[] bytes2 = null;
        try {
            is = socket.getInputStream();

//
//            isr = new InputStreamReader(is);//字节转字符
//
//            br = new BufferedReader(isr);//存进缓存
            byte[] bytes = new byte[1024];
            int read = is.read(bytes);
//
//

            if (read > 0) {

                bytes2 = Arrays.copyOfRange(bytes, 0, read);
                s1 = new String(bytes2);//byte转字符串
            }
//           String info = null;



//            System.out.println("我是服务器,客户端说:"+s1);
//            Person person = JSON.parseObject(s1, new TypeReference<Person>() {
//            });

            PersonTest.person person = PersonTest.person.parseFrom(bytes2); //protobuf转成对象
            System.out.println("person的名字" + s1);
            System.out.println("我是服务器,客户端说:" + person.getName());
            System.out.println("我是服务器,客户端说:" + person);
            System.out.println(String.format("反序列化得到的信息,姓名:%s", person.getName()));


            // socket.shutdownInput();//单向关闭输出流。并不会影响socket  如果是os.close()会影响socket。使得socket也会关闭
            //向客户端发送信息
            os = socket.getOutputStream();
            pw = new PrintWriter(os);
            pw.write("服务器欢迎你");

            pw.flush();
        } catch (Exception e) {
            // TODO: handle exception
        } finally {
            //关闭资源
            try {
                if (pw != null)
                    pw.close();
                if (os != null)
                    os.close();
//                if(br!=null)
//                    br.close();
//                if(isr!=null)
//                    isr.close();
                if (is != null)
                    is.close();
                if (socket != null)
                    socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}

SocketClient.java

import demo.PersonTest;

import java.io.*;
import java.net.Socket;

public class SocketClient {

    public static void main(String[] args) throws InterruptedException {
        try {
            // 和服务器创建连接
            Socket socket = new Socket("localhost", 8083);

            // 要发送给服务器的信息
            OutputStream os = socket.getOutputStream();//得到一个输出流对象

            ####使用的对象转json,json字符串,转bytes数组方式,传输字节流
//          Person person = new Person();//创建一个对象
//         person.setAge(10);
//         person.setHeight(100);
//
//           String s = JSON.toJSONString(person); //对象转json字符串
//          byte[] bytes = s.getBytes(); //字符串转bytes数组
//         os.write(bytes); //socket写出到服务器


//#####使用Protobuf序列化,转成字节通过字节流发给服务器端
            PersonTest.person.Builder personBuilder = PersonTest.person.newBuilder();
            personBuilder.setName("张山");
            PersonTest.person personTest = personBuilder.build();//创建的Person对象
            byte[] bytes = personTest.toByteArray();
            os.write(bytes);

            PrintWriter pw = new PrintWriter(os);//字符类型打印输出流
            pw.write("客户端发送信息");
            pw.flush();

            os.flush();
            socket.shutdownOutput();

            // 从服务器接收的信息
            InputStream is = socket.getInputStream();//返回的是字节输入流
            BufferedReader br = new BufferedReader(new InputStreamReader(is));//InputStreamRead将字节流转换为单个字符  //tcp以字节流的方式进行传输的//bufferedRead把它存在缓冲区里面
            String info = null;
            while ((info = br.readLine()) != null) {
                System.out.println("我是客户端,服务器返回信息:" + info);
            }

            br.close();
            is.close();
            os.close();
            pw.close();
            socket.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

SocketServer.java

import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;

public class SocketServer {

    public static void main(String[] args) {
        try {
            // 创建服务端socket
            ServerSocket serverSocket = new ServerSocket(8083);

            // 创建客户端socket
            Socket socket = new Socket();

            //循环监听等待客户端的连接
            while(true){
                // 监听客户端
                socket = serverSocket.accept();

                ServerThread thread = new ServerThread(socket);
                thread.start();

                InetAddress address=socket.getInetAddress();
                System.out.println("当前客户端的IP:"+address.getHostAddress());
            }
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }
    }

}

你可能感兴趣的:(socket)