参考:https://blog.csdn.net/u014209205/article/details/80461122
进行Socket编程, 常见使用的协议UDP/TCP
TCP:传输控制协议 。是专门设计用于在不可靠的因特网上提供可靠的,端到端的字节流通信的协议。它是一种面向连接的协议。TCP连接是字节流而非报文流。
UDP:用户数据报协议 。不需要建立连接,不可靠。
ProtocolBuffer
1、简介
参照: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();
}
}
}
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();
}
}
}
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();
}
}
}