转载请注明出处:http://blog.csdn.net/ecorefeng
作者:朱克锋
UDP(User Datagram Protocol)
(UDP)是 OSI 参考模型中一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务。是一个简单的面向数据报的传输层协议,IETF RFC 768是UDP的正式规范。 UDP 协议基本上是 IP 协议与上层协议的接口。 UDP 协议适用端口分别运行在同一台设备上的多个应用程序。
与 TCP 不同, UDP 并不提供对 IP 协议的可靠机制、流控制以及错误恢复功能等。由于 UDP 比较简单, UDP 头包含很少的字节,比 TCP 负载消耗少。
UDP 适用于不需要 TCP 可靠机制的情形,比如,当高层协议或应用程序提供错误和流控制功能的时候。 UDP 是传输层协议,服务于很多知名应用层协议,包括网络文件系统(NFS)、简单网络管理协议(SNMP)、域名系统(DNS)以及简单文件传输系统(TFTP)、动态主机配置协议(DHCP)、路由信息协议(RIP)和某些影音串流服务等等。
UDP协议有如下的特点:
1、UDP传送数据前并不与对方建立连接,即UDP是无连接的,在传输数据前,发送方和接收方相互交换信息使双方同步。
2、UDP不对收到的数据进行排序,在UDP报文的首部中并没有关于数据顺序的信息(如TCP所采用的序号),而且报文不一定按顺序到达的,所以接收端无从排起。
3、UDP对接收到的数据报不发送确认信号,发送端不知道数据是否被正确接收,也不会重发数据。
4、UDP传送数据较TCP快速,系统开销也少。
5、由于缺乏拥塞控制(congestion control),需要基于网络的机制来减小因失控和高速UDP流量负荷而导致的拥塞崩溃效应。换句话说,因为UDP发送者不能够检测拥塞,所以像使用包队列和丢弃技术的路由器这样的网络基本设备往往就成为降低UDP过大通信量的有效工具。数据报拥塞控制协议(DCCP)设计成通过在诸如流媒体类型的高速率UDP流中增加主机拥塞控制来减小这个潜在的问题。
从以上特点可知,UDP提供的是无连接的、不可靠的数据传送方式,是一种尽力而为的数据交付服务。
实例代码:
客户端:
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
public class Client {
public static void main(String[] args) {
try {
Socket s = new Socket("localhost",8888);
ReadThread rt = new ReadThread(s);
rt.start();
WriteThread wt = new WriteThread(s,"from client");
wt.start();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
服务器端:
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
public class Server {
List list = new ArrayList();
public static void main(String[] args) {
Server s = new Server();
s.go();
}
void go(){
try {
ServerSocket ss = new ServerSocket(8888);
while(true){
Socket s = ss.accept();
list.add(s);
//WriteThread wt = new WriteThread(s,"from server");
//wt.start();
sendToAll();
ReadThread rt = new ReadThread(s);
rt.start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
void sendToAll(){
for (int i = 0; i < list.size(); i++) {
Socket s = (Socket)list.get(i);
WriteThread wt = new WriteThread(s,"hello everyone");
wt.start();
}
}
}
读线程:
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
public class ReadThread extends Thread {
Socket s;
ReadThread(Socket s){
this.s = s;
}
public void run() {
InputStream in;
try {
in = s.getInputStream();
DataInputStream dis = new DataInputStream(in);
String str = null;
while((str=dis.readUTF())!=null){
//String str = dis.readUTF();
System.out.println(str);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
写线程:
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
public class WriteThread extends Thread {
Socket s;
String msg;
WriteThread(Socket s,String msg){
this.s=s;
this.msg = msg;
}
public void run() {
try {
OutputStream out = s.getOutputStream();
DataOutputStream dos = new DataOutputStream(out);
dos.writeUTF(msg);
} catch (IOException e) {
e.printStackTrace();
}
}
}
--end--