1.UDP是面向报文的
发送方UDP 对应用程序交下来的报文,在添加首部后就向下交付 IP层。UDP对应用层交下来的报文,既不合并,也不拆分,而是保留这些报文的边界。应用层交给 UDP多长的报文,UDP就照样发送,即一次发送一个报文。接收方 UDP对 IP层交上来的 UDP 用户数据报,在去除首部后就原封不动地交付上层的应用进程,一次交付一个完整的报文。
2.UDP特点
UDP(User Datagram Protocol)用户数据报,是一种无连接,不可靠的传输层协议。
无连接:正式通信前不必与对方先建立连接,不管对方状态就直接发送。
不可靠:UDP 包在传输过程中由于数据的缺失被丢弃不会进行重传,没有流量控制, 没有拥塞控制。UDP有不提供数据报分组、组装和不能对数据包的排序的缺点,也就是说,当报文发送之后,是无法得知其是否安全完整到达的。
3.使用UDP的场景
它不属于连接型协议,因而具有资源消耗小,处理速度快的优点,所以通常音频、视频和普通数据在传送时使用UDP较多,因为它们即使偶尔丢失一两个数据包,也不会对接收结果产生太大影响。
4.服务器端代码
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
public class UDPServer {
final int buffSize = 2048;
DatagramSocket sock;
String request;
String response;
InetAddress clientAddr;
int clientPort;
UDPServer (DatagramSocket s){
sock = s;
}
void getRequest(){
try{
byte [] recvBuff = new byte [buffSize];
DatagramPacket recvPacket = new DatagramPacket(recvBuff , buffSize);
sock.receive(recvPacket);
recvBuff = recvPacket.getData();
request = new String (recvBuff, 0, recvBuff.length);
clientAddr = recvPacket.getAddress();
clientPort = recvPacket.getPort();
}catch (Exception ex){
}
}
void process (){
//添加代码进来处理请求,创建响应
System.out.println("处理请求创建响应");
response = "request:"+request;
}
void sendResponse(){
try {
byte [] sendBuff = new byte [buffSize];
sendBuff = response.getBytes();
DatagramPacket sendPacket = new DatagramPacket(sendBuff, sendBuff.length, clientAddr, clientPort);
sock.send(sendPacket);
}catch (Exception e){
System.out.println(e);
}
}
public static void main (String [] args ) throws SocketException {
final int port = 8989;
DatagramSocket sock = new DatagramSocket(port);
while (true){
UDPServer server = new UDPServer (sock);
server.getRequest();
server.process();
server.sendResponse();
}
}
}
5.客户端代码
import java.net.*;
public class UDPClient {
final int buffSize = 2048;
DatagramSocket sock;
String request;
String response;
InetAddress servAddr;
int servPort;
UDPClient(DatagramSocket s, String sName , int sPort ) throws UnknownHostException {
sock = s;
servAddr = InetAddress.getByName(sName);
servPort = sPort;
}
void makeRequest(){
//创建请求字符串的代码
request ="This UDP Packet";
}
void sendRequest (){
try {
byte [] sendBuff = new byte [buffSize];
sendBuff = request.getBytes() ;
DatagramPacket sendPacket = new DatagramPacket(sendBuff, sendBuff.length, servAddr, servPort);
sock.send(sendPacket);
}catch (Exception ex){
}
}
void getResponse (){
try {
byte [] recvBuff = new byte [buffSize];
DatagramPacket recvPacket = new DatagramPacket(recvBuff, buffSize);
sock.receive(recvPacket);
recvBuff = recvPacket.getData();
response = new String (recvBuff, 0, recvBuff.length);
}catch (Exception ex){}
}
void UseResponse (){
//使用响应的字符串代码
System.out.println();
}
void close (){
sock.close();
}
public static void main (String [] args) throws SocketException, UnknownHostException {
final int servPort =8989;
final String servName ="localhost";
DatagramSocket sock = new DatagramSocket();
UDPClient client = new UDPClient (sock, servName, servPort);
client.makeRequest();
client.sendRequest();
client.getResponse();
client.UseResponse();
client.close();
}
}