C/S
结构:即客户端/服务器结构,是软件系统体系结构;充分利用两端硬件环境的优势,将任务合理分配到Client
和Server
端来实现,降低了系统的通信开销。
Socket
套接字,是一个对TCP/IP
协议进行封装的编程调用接口,属于传输层,即通过Socket
,才可以在Android
平台上进行TCP/IP
协议开发,为通信双方的数据传输提供通道。
文章图片
Socket
的使用可以基于TCP
或者UDP
协议。
TCP
协议(Transmission Control Protocol
),即传输控制协议,是一种传输层通信协议。基于TCP
的应用层协议由FTP
、Telnet
、SMTP
、HTTP
、POP3
和DNS
。 特点是:
- 面向连接:指的是要使用
TCP
传输数据,必须先建立TCP
连接,传输完成后释放连接; - 全双工通信:即一旦建立了
TCP
连接,通信双方可以在任何时候发送数据; - 可靠:指的是通过
TCP
连接传输的数据,无差错、不丢失、无重复,并且按序到达; - 面向字节流:流指的是在进程中流入流出的字符序列。简单来说,虽然有的时候传输的数据流太大,
TCP
报文有长度限制,不能一次性传输完,需要把它分成好几个数据块,但又要保证可靠性,接收方可以按顺序接收数据块然后重组成之前的数据流;
UDP
协议(User Datagram Protocol
),即用户数据报协议,是一种传输层通信协议。基于UDP
的应用层协议有TFTP
、SNMP
和DNS
。 特点是:- 无连接:
UDP
传输数据不需要建立连接; - 不可靠:因为
UDP
数据包发出去就不管了,不管它会不会到达,可能会出现丢包的现象; - 面向报文:数据报文,相当于一个数据包。不管应用层交给
UDP
多大的数据包,UDP
都照样发送,不会像TCP
那样拆分; - 没有阻塞控制:阻塞是指通信子网中某一部分的分组数量过多,使得该部分晚了来不及处理,以至隐去这部分乃至于整个网络性能下降的情况。
TCP
建立连接后如果遇到类似的情况,导致发送的数据无法到达目的地,它会不断的重复,就会使得网络越来越阻塞,所以需要一个复杂的原理来控制阻塞。而UDP
没有个这个问题;
UDP
的应用场景:很多的实时应用,如IP
电话、实时视频会议等要求源主机以很快的速率发送数据,并且允许在网络阻塞时可以丢失一些数据,但是要求不能有太大的延迟,这个时候就可以考虑UDP
。Android
中客户端与服务端的通信方式有两种:HTTP
和Socket
:Http
属于应用层,采用请求-响应的方式发送数据,即建立网络连接后,在客户端向服务端发送请求后,服务端才向客户端发送数据;Socket
属于传输层,采用主动发送数据的方式,即建立网络连接后,服务端可以主动发送消息给客户端,而不需要客户端向服务端发送请求;
Socket
的使用类型主要有两种:- 流套接字(
streamsocket
):基于TCP
协议,采用流的方式提供可靠的字节流服务; - 数据报套接字(
datagramsocket
):基于UDP
协议,采用数据报文提供数据打包发送的服务;
TCP
协议的Socket
:客户端创建一个Socket
对象,指定服务器端的IP
地址和端口号,通过InputStream
读取服务端发送的数据:try {
Socket socket = new Socket("172.16.10.108", 8080);
InputStream inputStream = new FileInputStream("e://a.txt");
OutputStream outputStream = socket.getOutputStream();
byte buffer[] = new byte[4 * 1024];
int temp = 0;
while ((temp = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, temp);
}
outputStream.flush();
} catch (IOException e) {
e.printStackTrace();
}
基于
UDP
协议的Socket
:客户端创建一个DatagramSocket
对象,并且指定监听的接口:// 客户端发送数据
try {
DatagramSocket socket = new DatagramSocket(1985);
InetAddress inetAddress = InetAddress.getByName("192.168.1.32");
String string = "哈哈哈哈哈哈";
byte[] data = https://www.it610.com/article/string.getBytes();
DatagramPacket packet = new DatagramPacket(data, data.length, inetAddress, 10025);
socket.send(packet);
} catch (IOException e) {
e.printStackTrace();
}// 客户端接收数据
try {
DatagramSocket socket = new DatagramSocket(1985);
byte[] data = new byte[4 * 1024];
DatagramPacket packet = new DatagramPacket(data, data.length);
socket.receive(packet);
String result = new String(packet.getData(), packet.getOffset(), packet.getLength());
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
参考
【网络请求(四)—Socket】@Android:这是一份很详细的Socket使用攻略
基于android的Socket通信
Android必备: Socket编程的了解与学习整理
推荐阅读
- flutter|跨平台开发方案调研
- 程序员|Android面试总结,开发者必备的顶级Android开发工具,跳槽薪资翻倍
- 食之无味(App Startup 可能比你想象中要简单)
- 使用 DialogX 快速构建 Android App
- android 自定义View: 视差动画
- webview|CSS原生修改select 样式,实现下拉三角括号
- Anroid|Android Studio开发中的各种开源API
- Android|Android studio大作业-体育场预约管理系统
- android|Android Studio 实现简易的个人信息录取(含源码)