安卓基于TCP\UDP 协议通讯

前言:如果觉得太长可以直接看实例,个人觉得协议就是一些人根据某些需求而共同达成的约定。

TCP(Transport Control Protocol)

面向连接的能够提供可靠的流式数据传输的协议。类似于打电话的过程。
(URL、URLConnection、Socket、ServerSocket等类都使用TCP协议进行网络通讯)

安卓基于TCP\UDP 协议通讯_第1张图片
TCP通讯原理图.png

TCP三次握手

所谓三次握手(Three-Way Handshake)即建立TCP连接,就是指建立一个TCP连接时,需要客户端和服务端总共发送3个包以确认连接的建立。在socket编程中,这一过程由客户端执行connect来触发,整个流程如下图所示:

  • 第一次握手:Client将标志位SYN置为1,随机产生一个值seq=J,并将该数据包发送给Server,Client进入SYN_SENT状态,等待Server确认。
  • 第二次握手:Server收到数据包后由标志位SYN=1知道Client请求建立连接,Server将标志位SYN和ACK都置为1,ack=J+1,随机产生一个值seq=K,并将该数据包发送给Client以确认连接请求,Server进入SYN_RCVD状态。
  • 第三次握手:Client收到确认后,检查ack是否为J+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=K+1,并将该数据包发送给Server,Server检查ack是否为K+1,ACK是否为1,如果正确则连接建立成功,Client和Server进入ESTABLISHED状态,完成三次握手,随后Client与Server之间可以开始传输数据了。

TCP四次握手(其实就是断开TCP连接)

由于TCP连接时全双工的,因此,每个方向都必须要单独进行关闭,这一原则是当一方完成数据发送任务后,发送一个FIN来终止这一方向的连接,收到一个FIN只是意味着这一方向上没有数据流动了,即不会再收到数据了,但是在这个TCP连接上仍然能够发送数据,直到这一方向也发送了FIN。首先进行关闭的一方将执行主动关闭,而另一方则执行被动关闭。

  • 第一次挥手:Client发送一个FIN,用来关闭Client到Server的数据传送,Client进入FIN_WAIT_1状态。
  • 第二次挥手:Server收到FIN后,发送一个ACK给Client,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),Server进入CLOSE_WAIT状态。
  • 第三次挥手:Server发送一个FIN,用来关闭Server到Client的数据传送,Server进入LAST_ACK状态。
  • 第四次挥手:Client收到FIN后,Client进入TIME_WAIT状态,接着发送一个ACK给Server,确认序号为收到序号+1,Server进入CLOSED状态,完成四次挥手。

UDP(User Datagram Protocol)

非面向连接的提供不可靠的数据包式的数据传输协议。类似于从邮局发邮件。
(DatagramPacket、DatagramSocket、MulticastSocket等类使用UDP协议进行网络通讯)

比较:

TCP有建立时间
UDP传输有大小限制:64k以内
TCP的应用:Telnet(远程登录)、ftp(文件传输)
UDP的应用:ping命令

实例:

TCP通讯
//创建socket
Socket socket = new Socket("127.8.0.1",8080);

//创建输出流
PrintWriter os =new PrintWriter(socket.getOutputStream());
//创建输入流
BufferedReader is = new BufferedReader(new InputStreamReader(socket.getInputStream()));
.....以下部分变成流的读写操作了......
......总结起来,建立连接之后其实变成了 I/O读写操作......

//###完成通讯之后关闭流###
// 关闭输出流
 os.close();
//关闭输入流
 is.close();
 socket.close(); 
UDP通讯
###接收数据###
 DatagramSocket  socket =new DatagramSocket();
DatagramPacket packet =new DatagramPacket(buf,256);

buf:数据接收的对象 如:byte[] buf =new byte[256]; 
256:字节长度

用packet接收数据
socket.receive(packet);
//把数据转字符串
String received =new String(packet.getData());

###发数据###
DatagramPacket packet =new DatagramPacket(buf,buf.length,address,port);
buf:数据发送的对象     如:byte[] buf =new byte[256]; 
buf.length:数据字节长度 
address:发送的地址(比如:www.baidu.com或者192.168.9.2)
如:
InetAddress address = InetAddress.getByName("192.168.9.2");
port:端口号(如8080等)

发送packet数据
socket.send(packet);

你可能感兴趣的:(安卓基于TCP\UDP 协议通讯)