UDP 是User Datagram Protocol的简称, 中文名是用户数据报协议,是OSI(Open System Interconnection,开放式系统互联) 参考模型中一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务。
在选择使用协议的时候,选择UDP必须要谨慎。在网络质量令人十分不满意的环境下,UDP协议数据包丢失会比较严重。但是由于UDP的特性:它不属于连接型协议,因而具有资源消耗小,处理速度快的优点,所以通常音频、视频和普通数据在传送时使用UDP较多,因为它们即使偶尔丢失一两个数据包,也不会对接收结果产生太大影响。比如我们聊天用的ICQ和QQ就是使用的UDP协议。
UDP协议比较简单,实现容易,但它没有确认机制, 数据包一旦发出,无法知道对方是否收到,因此可靠性较差,为了解决这个问题,提高网络可靠性,TCP协议就诞生了,TCP即传输控制协议,是一种面向连接的、可靠的、基于字节流的通信协议。简单来说TCP就是有确认机制的UDP协议,每发出一个数据包都要求确认,如果有一个数据包丢失,就收不到确认,发送方就必须重发这个数据包。总之,TCP的可靠性优于UDP。
一个数据包由以下部分组成:
1、字节数组byte[ ]
2、length 数据有效长度
3、通讯地址IP(自己的IP+别人的IP)
4、端口号
DatagramSocket()负责发送和接受信息{
1、send()2、receive():接受=复制
UDP通讯两边一定要约定好数据的长度,只要不超过长度,对方法的包就能收。如果超过长度,则要分解成设定长度的字节数组才能收。
package 网络;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
public class udpServer {
public static void main(String[] args) throws IOException {
DatagramSocket poster =new DatagramSocket(9999);
DatagramPacket packet=new DatagramPacket(new byte[1024], 1024);
System.out.println("等待接收数据包!");
poster.receive(packet);//接收==复制
byte[] temp=packet.getData();//取出数据
int length=packet.getLength();
String str=new String(temp, 0, length);//将字节数组还原成字符串
//得到的temps数组远远不止6个字节,所以输出会有很多空格,从数组的0索引开始包装字符串,length为字符串长度
System.out.println(str);
}
}
package 网络;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InterfaceAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import javax.xml.ws.handler.MessageContext;;
public class udpClient {
public static void main(String[] args) throws IOException {
DatagramSocket poster=null;
try {
poster=new DatagramSocket();
} catch (SocketException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
String mesg="你好!";
try {
DatagramPacket packet = new DatagramPacket(mesg.getBytes(),mesg.getBytes().length,InetAddress.getByName("127.0.0.1"),9999);
poster.send(packet);
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
发送对象或各种非字符串类型的数据
package 网络;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
public class udpObjectClient {
public static void main(String[] args) throws IOException {
DatagramSocket poster=null;
poster=new DatagramSocket();
int a=220;
double b=2332.2;
Student s=new Student(22, "张三");
//把上面的数据转换成字节数组
ByteArrayOutputStream by=new ByteArrayOutputStream();
ObjectOutputStream objout=new ObjectOutputStream(by);
objout.writeInt(a);
objout.writeDouble(b);
objout.writeObject(s);
objout.flush();
byte[] t=by.toByteArray();//得到数据
objout.close();
DatagramPacket packet =new DatagramPacket(t, t.length,InetAddress.getByName("127.0.0.1"),9999);
poster.send(packet);
}
}
/*
* 1.InetAddress.getByName()
通过主机名获取对应的ip地址:(当然也支持通过IP地址来查找主机名)
该方法会建立与本地DNS的一个连接,来获取名称和地址之间的映射关系。(如果本地DNS缓存了地址,就不再获取连接。)
*/
package 网络;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import 网络.*;
public class udpObjectServer {
public static void main(String[] args) throws Exception {
DatagramSocket poster =new DatagramSocket(9999);
//创建好缓存包
DatagramPacket packet=new DatagramPacket(new byte[1024],1024);
poster.receive(packet);//接收==复制
byte[] data=packet.getData();
//读字节数组
int length=packet.getLength();//长度已将被覆盖掉了,是对方发过来的有效长度不再是初始化的长度1024了。
ByteArrayInputStream bis=new ByteArrayInputStream(data);
ObjectInputStream objin=new ObjectInputStream(bis);
int a=objin.readInt();
double b=objin.readDouble();
Student s = (Student)objin.readObject();
System.out.println(a + ":" + b + ":" + s);
}
}
package 网络;
import java.io.Serializable;
public class Student implements Serializable {
@Override
public String toString() {
return "Student [id=" + id + ", name=" + name + "]";
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
private int id;
private String name;
public Student(int id, String name) {
this.id = id;
this.name = name;
}
}