通信,大家都比较了解,日常生活中非常之多,下面给大家来一段抖音比较流行的。(绿帽子之通信系列)
大概说下通信基础(主要介绍下传输层协议TCP,UDP两个协议)
TCP是怎么样建立连接的,怎么进行数据传输的,是否安全?
三次握手:
a).第一次握手:客户端首先发送一个SYN数据包,并且定义seq=x,然后客户端进入SYN_SENT状态,并且等待服务器的等待。
b).第二次握手:服务端收到SYN包之后,必须确认客户端的包(ACK=x+1),同时自己也发送一个包SYN=y,此时服务端进入了SYN_RCVD状态,
c).第三次握手:呵护短收到包之后,然后向服务器端发送一个ACK=y+1,发送完毕之后,服务器和客户端都进入了retablished状态,完成三次握手。
开始进行数据传输。
四次挥手:
由于TCP连接是全双工的,因此每个方向都必须单独进行关闭。这个原则是当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向的连接。收到一个 FIN只意味着这一方向上没有数据流动,一个TCP连接在收到一个FIN后仍能发送数据。首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。
(1)客户端A发送一个FIN,用来关闭客户A到服务器B的数据传送。
(2)服务器B收到这个FIN,它发回一个ACK,确认序号为收到的序号加1。和SYN一样,一个FIN将占用一个序号。
(3)服务器B关闭与客户端A的连接,发送一个FIN给客户端A。
(4)客户端A发回ACK报文确认,并将确认序号设置为收到序号加1。
TCP代码测试(客户端与服务端):
服务端;
package com.aaa.demosocket;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
/**
* TCP服务端
* @author wzder
*
*/
public class TCPServer {
public static void main(String[] args) throws Exception {
System.out.println("服务端程序启动了啊");
//创建一个Socket连接,并且制定端口
ServerSocket serverSocket=new ServerSocket(8080);
//等待客户端请求
Socket accept = serverSocket.accept();
//创建一个输入流
InputStream inputStream=accept.getInputStream();
//转换成String类型
byte[] bs=new byte[1024];
int len = inputStream.read(bs);
String string=new String(bs,0,len);
System.out.println("读取的服务器内容:"+string);
//关闭流
serverSocket.close();
}
}
可以拿浏览器 localhost:8080直接访问就能看到效果的
UDP测试代码:
服务端:
package com.aaa.demosocket;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
/**
* UDP服务端
* @author wzder
*
*/
public class UDPServer {
public static void main(String[] args) throws Exception {
System.out.println("UDP服务端已经启动了啊");
DatagramSocket datagramSocket=new DatagramSocket(8081);
System.out.println("udp服务器端启动连接....");
DatagramSocket ds = new DatagramSocket(8080);
byte[] bytes = new byte[1024];
DatagramPacket dp = new DatagramPacket(bytes, bytes.length);
// 阻塞,等待接受客户端发送请求
ds.receive(dp);
System.out.println("来源:"+dp.getAddress()+",端口号:"+dp.getPort());
// 获取客户端请求内容
String str=new String(dp.getData(),0,dp.getLength());
System.out.println("str:"+str);
ds.close();
}
}
可以拿浏览器 localhost:8080直接访问就能看到效果的
两种协怎么同时接受到多个请求呢?:
这就牵扯到多线程了,一般建议大家使用线程池,能够有效的节省内存,如果不知道线程池的可以看下:线程池创建的几种方式
package com.aaa.demosocket;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* TCP服务端
* @author wzder
*
*/
public class TCPServer {
public static void main(String[] args) throws Exception {
ExecutorService newCachedThreadPool = Executors.newCachedThreadPool();
System.out.println("服务端程序启动了啊");
//创建一个Socket连接,并且制定端口
ServerSocket serverSocket=new ServerSocket(8080);
try {
while(true){
//等待客户端请求
Socket accept = serverSocket.accept();
newCachedThreadPool.execute( new Runnable() {
public void run() {
try {
InputStream inputStream=accept.getInputStream();
byte[] bs=new byte[1024];
int len = inputStream.read(bs);
String string=new String(bs,0,len);
System.out.println("读取的服务器内容:"+string);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
} catch (Exception e) {
e.printStackTrace();
}finally {
//关闭流
serverSocket.close();
}
}
}
可以拿浏览器访问,发现tcp服务端并没有关闭。
两种通信的区别:
TCP:
a、建议连接,形成传输数据的通道.
b、在连接中进行大数据量传输,以字节流方式
c 通过三次握手完成连接,是可靠协议
d 必须建立连接m效率会稍低
UDP:
a、是面向无连接, 将数据及源的封装成数据包中,不需要建立连接
b、每个数据报的大小在限制64k内
c、因无连接,是不可靠协议
d、不需要建立连接,速度快
在实战中学习,在快乐中成长