0302 网络通信
网络通信协议
目前网络通信协议应用最广泛的是Tcp/Ip协议,包括Tcp协议和Ip协议,UDP协议和协议组
IP协议和端口号
IP协议是用32位二进制的数字组成,4位字节,一个字节代表八位,转成十进制是四个十进制的数组成,每个数字在0-255之间,例:00001010 00000000 00000000 00000001 等于10.0.0.1
端口号是两个字节,是16位的二进制组成,转成十进制是0-65535范围之内 0~1023之间的端口号用于一些知名的网络服务和应用,用户的普通应用程序需要使用1024以上的端口号
InetAddress类
该类中提供了许多关于IP地址相关的方法
(1)getByName(String name) 返回值是一个InetAddress对象,name代表是自己电脑的名字
(2)getLocalHost() 返回本地主机 返回值是一个InetAddress对象。
(3)getHostName() 获取主机名字
(4)getHostAddress() 获取主机的ip地址
代码展示
public class Demo01 { public static void main(String[] args) throws UnknownHostException { InetAddress inet=InetAddress.getByName("LAPTOP-T3L09M8L"); System.out.println(inet); //获取本机 InetAddress inet2=InetAddress.getLocalHost(); System.out.println(inet2); //获取主机名 System.out.println(inet2.getHostName()); //获取ip地址 System.out.println(inet2.getHostAddress()); } } 运行结果 LAPTOP-T3L09M8L/192.168.1.185 LAPTOP-T3L09M8L/192.168.1.185 LAPTOP-T3L09M8L 192.168.1.185
UDP协议和TCP协议
1、UDP 无连接通信协议,即在数据传输时,不建立逻辑连接关系,也就是说发送端不知道接收端在不在 就发送数据,同样接收端接收到数据也不会发出接收到数据的信息。
UDP消耗资源小,通信效率高,通常应用于音频视频的数据传输,例如视频会议,偶尔卡一下,不会造成数据的丢失。
由于UDP是无连接的 所以在传输数据时并不能保证数据的完整性,所以在传输重要文件的时候不建议使用UDP传输。
2、TCP协议,是面向链接的通信协议,在发送端和接收端建立逻辑链接关系,保证数据准确无误的传输。TCP传输必须明确客户端和服务器端,客户端发出请求,每次创建链接都要经过 三次握手
第一次握手:当客户端发出请求等待服务器应答,第二次握手:服务器收到请求,并发出响应,第三次握手:客户端收到响应后再次发出确认信息,最后建立链接
UDP通信
这样写UDP发送数据的程序呢
提供了DatagramPacket打包拆包类,和DatagramSocket 运输发送和接受的类
DatagramPacket构造方法
DatagramPacket(byte[] buf, int length)用于接收ilength长度的数据包
DatagramPacket(byte [] buf, int 1 ength, InetAddress address, int Dort)将length长度的数据包,发送给address主机,Dort端口号
DatagramPacket常用拆包方法
getAddress()返回主机的Ip地址
getPort()返回端口号
getLength()返回数据的长度
DatagramSocket 构造方法
DatagramSocket ()用于发送端
DatagramSocket (int Dort)用于接收端
代码展示 发送端
public class UDPSend { //发送端 public static void main(String[] args) throws IOException { byte[] bytes="你好".getBytes(); InetAddress inet=InetAddress.getLocalHost(); //创建数据打包对象 封装发送的数据地址 接收端ip和端口号 DatagramPacket dp=new DatagramPacket(bytes, bytes.length,inet,9000); //创建快递公司对象 DatagramSocket ds=new DatagramSocket(); //发送数据 ds.send(dp); //释放资源 ds.close(); } }
接收端
public class UDPResive { //接收端 public static void main(String[] args) throws IOException { //创建快递公司明确端口号 DatagramSocket ds=new DatagramSocket(9000); //创建字节数组接受数据 byte[] bytes=new byte[1024]; //创建拆白对象 DatagramPacket dp=new DatagramPacket(bytes, bytes.length); //接受数据 ds.receive(dp); //拆包 //获取发送端ip地址 String ip=dp.getAddress().getHostAddress(); //获取发送端端口号 int port=dp.getPort(); //获取数据长度 int len=dp.getLength(); System.out.println("ip地址为:"+ip+"端口号为:"+port+"发送的内容为:"+new String(bytes,0,len)); ds.close(); } }
创建循环发送输入的内容
public class UDPSend { //发送端 public static void main(String[] args) throws IOException { Scanner sc=new Scanner(System.in); InetAddress inet=InetAddress.getByName("192.168.1.171"); //创建快递公司对象 DatagramSocket ds=new DatagramSocket(); while(true){ byte[] bytes=sc.next().getBytes(); //创建数据打包对象 封装发送的数据地址 接收端ip和端口号 DatagramPacket dp=new DatagramPacket(bytes, bytes.length,inet,9000); //发送数据 ds.send(dp); } //释放资源 //ds.close(); } } public class UDPResive { //接收端 public static void main(String[] args) throws IOException { //创建快递公司明确端口号 DatagramSocket ds=new DatagramSocket(9000); //创建字节数组接受数据 byte[] bytes=new byte[1024]; while(true){ //创建拆白对象 DatagramPacket dp=new DatagramPacket(bytes, bytes.length); //接受数据 ds.receive(dp); //拆包 //获取发送端ip地址 String ip=dp.getAddress().getHostAddress(); //获取发送端端口号 int port=dp.getPort(); //获取数据长度 int len=dp.getLength(); System.out.println("ip地址为:"+ip+"端口号为:"+port+"发送的内容为:"+new String(bytes,0,len)); } //ds.close(); } }
运行结果