- 本文参考https://www.jianshu.com/p/089fb79e308b精简并结合自己的一点理解,所参考的文章更为详细
一.Socket定义
套接字,是应用层 与 TCP/IP 协议族通信的中间软件抽象层,表现为一个封装了 TCP / IP协议族 的编程接口(API)
- Socket不是一种协议,而是一个编程调用接口(API),属于传输层(主要解决数据如何在网络中传输),在Android上,我们通过Socket来进行基于TCP或UDP协议的网络通信开发
- 成对出现,一对套接字:
Socket ={(IP地址1:PORT端口号),(IP地址2:PORT端口号)}
- 一个 Socket 实例 唯一代表一个主机上的一个应用程序的通信链路
示意图:
通信原理图:
二.建立连接过程
客户端
- 创建一个Socket实例,构造方法传入
ip
和port
- 在创建Socket实例的构造函数返回前,会调用
connect(SocketAddress endpoint)
去建立连接,TCP的话会三次握手 - 连接建立以后通过
socket.getInputStream()
和socket.getOutputStream()
来与服务端进行通信
服务端
- 创建一个ServerSocket实例,传入监听的
port
- 调用
accept()
方法,将进入阻塞状态,等待客户端的请求 - 当一个新请求到来时,将
accept
方法将创建一个新的Socket
套接字返回 - 连接建立以后通过
socket.getInputStream()
和socket.getOutputStream()
来与服务端进行通信
三.使用步骤
- 这里仅就TCP而言举例
// 步骤1:创建客户端 & 服务器的连接
// 创建Socket对象 & 指定服务端的IP及端口号
Socket socket = new Socket("192.168.1.32", 1989);
// 判断客户端和服务器是否连接成功
socket.isConnected());
// 步骤2:客户端 & 服务器 通信
// 通信包括:客户端 接收服务器的数据 & 发送数据 到 服务器
<-- 操作1:接收服务器的数据 -->
// 步骤1:创建输入流对象InputStream
InputStream is = socket.getInputStream()
// 步骤2:创建输入流读取器对象 并传入输入流对象
// 该对象作用:获取服务器返回的数据
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
// 步骤3:通过输入流读取器对象 接收服务器发送过来的数据
br.readLine();
<-- 操作2:发送数据 到 服务器 -->
// 步骤1:从Socket 获得输出流对象OutputStream
// 该对象作用:发送数据
OutputStream outputStream = socket.getOutputStream();
// 步骤2:写入需要发送的数据到输出流对象中
outputStream.write(("Carson_Ho"+"\n").getBytes("utf-8"));
// 特别注意:数据的结尾加上换行符才可让服务器端的readline()停止阻塞
// 步骤3:发送数据到服务端
outputStream.flush();
// 步骤3:断开客户端 & 服务器 连接
socket.close();