1.简介
在osi(七层网络架构:应用层,表示层,会话层,传输层,网络层,数据链路层,物理层)中,TCP和UDP属于同一层即传输层,IP属于网络层。TCP在传输时,需要建立稳定可靠的连接(三次握手和四次挥手)。UDP则不需要,只需指定数据报所发送的地址和端口即可。TCP/UDP各有优缺点。TCP比较稳定,但是效率低(建立连接的过程中比较耗时)。UDP不稳定(没有稳定连接可能会丢包),但是效率比较高。
2.如何去创建UPD
首先我们看一下UDP中的一些方法
1.DatagramSocket 套接字Socket
DatagramSocket(); //没有指定端口号,系统会自己分配一个端口号
构造数据报套接字并将其绑定到本地主机的任何可用端口。
DatagramSocket(int port); //自己确定端口号
构造数据报套接字并将其绑定到本地主机上的指定端口。
receiver(DatagramPacket p); //类似与TCP里面的accept() 阻塞,将数据报放入p中
从次套接字发送数据包
2.DatagramPacket 数据报
DatagramPacket(byte []buf,int length); //解包
构造一个DatagramPacket用于接受长度的数据报length。
DatagramPacket(byte []buf,int length,InetAddress address,int port); //打包
构造用于发送长度的分组的数据报包length指定主机上的端口号。
getAddress();
返回该数据报发送或接收数据报的计算机的IP地址。
getData();
getLength();
getPort();
返回发送数据报的远程主机上的端口号,或从中接收数据报的端口号。
3.如何去使用UDP
第一步:创建Server
package UDP;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class Server {
public static void main(String[] args) throws Exception {
DatagramSocket dtsk=new DatagramSocket(6656);//创建UDP实例 指定端口号
byte bytes[]=new byte[1024];//创建一个byte数组 1kb
//接收消息 bytes用于接受传入数据报的缓存
DatagramPacket packet=new DatagramPacket(bytes,bytes.length);//读取的最大字节数为bytes的长度
dtsk.receive(packet);//开启监听 阻塞 将消息放入packet中
//解包 得到缓冲区的数据(返回一个byte数组)
String str=new String(packet.getData(),0,packet.getLength());
//可通过DatagramPacket对象获得对方 地址 端口号
System.out.println(str+"对方IP: "+packet.getAddress()+" 端口号:"+packet.getPort());
//发消息
String take="哈哈哈\n";
byte bt[]=take.getBytes();
//打包 将指定信息以byte数组的形式 通过 IP地址 端口号 打成包
DatagramPacket takepacket=new DatagramPacket(bt,bt.length,packet.getAddress(),packet.getPort());
dtsk.send(takepacket);//将数据包发送出去
}
}
第二步:创建Client
package UDP;
import java.net.*;
public class Client {
public static void main(String[] args) throws Exception {
String str = "你好啊!\n";
DatagramSocket dtsk = new DatagramSocket();//如果不指定端口号 系统会自动分配一个端口号
byte bytes[] = str.getBytes();
//发送消息
//打包
DatagramPacket packet = new DatagramPacket(bytes, bytes.length, InetAddress.getByName("localhost"), 6656);
//发送
dtsk.send(packet);//发送消息
//接受消息
byte bt[] = new byte[1024];
DatagramPacket takespacket = new DatagramPacket(bt, bt.length);//解包
dtsk.receive(takespacket);//监听
//得到包中数据
String take = new String(takespacket.getData(), 0, takespacket.getLength());
System.out.println(take+"对方IP: "+takespacket.getAddress()+" 端口号:"+takespacket.getPort());
}
}
第三步:开启服务器和客户端
运行结果:
客户端会将消息发送到服务器,也会收到服务器发送的消息,并且显示对方的IP地址和端口号。由于我们在创建客户端时,没有指定客户端的端口号。在服务器端可以看出,系统给我们分配了一个端口号:57738。
总结
当我们用UDP传输的过程中。发送时,首先将要发送的数据通过DatapramPacket打包后通过DatapramSocket发送到对方。接收时,同过DatapramSocket得到对方的数据包,然后通过DatapramPacket解包。发送的时候需要在指定对方的IP地址和端口号(就好比写信,需要在信封上写上收信人的地址,数据包就相当于信封)。在TCP里面只需要在服务器端开启监听,就可以达到,双方彼此通讯。而在UDP中需要双方都开启监听(receive()),才能彼此通讯。因为UDP的数据是以数据包的形式进行传输的,没有建立稳定的连接。接受消息时需要解包,有数据包才能解包,所以要调用receive()方法获得包。
每日鸡汤:拥有的时候好好珍惜,失去的时候淡然处之。
Over!