一般說明
在TCP/IP協議族中,UDP和TCP同樣位於傳輸層,使用者資料報是UDP協議中的概念.
UDP協議提供面向事務的簡單不可靠資訊傳送服務,它不提供對 IP 協議的可靠機制、流量控制以及錯誤恢複功能.
UDP 協議基本上是IP 協議與上層協議的介面,從整個使用者資料在各層的封裝看,UDP報文格式相當簡單:
| 16 |
32bit |
| Source port源連接埠 |
Destination port目標連接埠 |
| Length 報文長度(單位是位元組,包括首部和使用者資料區) |
Checksum(校正和) |
| Data |
由於校正和的原因,UDP還引入了偽首部,這導致了UDP和IP層的關係過於密切,破壞了分層原則.
Java資料報支援
包java.net中提供了兩個類DatagramSocket和DatagramPacket用來支援資料報通訊,DatagramSocket用於在程式之間建立傳送資料報的通訊串連, DatagramPacket則用來表示一個資料報。
DatagramSocket代表發送和接收資料報的通訊端,一個資料通訊端是為包遞送服務的發送和接收點,在一個資料通訊端上,每個被發送和接收的包都被獨立的定址和路由,從一台機器到另一台機器上發送的多個包有不同的路由,任意的抵達順序.
對於DatagramSocket,UDP廣播發送總是使能的(那是預設設定).為了接收廣播包這個類執行個體應該綁定到通用地址(wildcard address).在某些實現中,當被綁定到更多特定地址上的時候廣播包也可以接收.
例如:
DatagramSocket s = new DatagramSocket(null);
s.bind(new InetSocketAddress(8888));
這等同於:
DatagramSocket s = new DatagramSocket(8888);
兩種情況都會建立一個能在連接埠8888上接收廣播的DatagramSocket執行個體.
| Constructor Summary |
|
DatagramSocket() Constructs a datagram socket and binds it to any available port on the local host machine. |
protected |
DatagramSocket(DatagramSocketImpl impl) Creates an unbound datagram socket with the specified DatagramSocketImpl. |
|
DatagramSocket(int port) Constructs a datagram socket and binds it to the specified port on the local host machine. |
|
DatagramSocket(int port, InetAddress laddr) Creates a datagram socket, bound to the specified local address. |
|
DatagramSocket(SocketAddress bindaddr) Creates a datagram socket, bound to the specified local socket address. |
其中,port指明socket所使用的連接埠號碼,如果未指明連接埠號碼,則把socket串連到本地主機上一個可用的連接埠。laddr指明一個可用的本地地址。給出連接埠號碼時要保證不發生連接埠衝突,否則會產生SocketException類例外。
用資料報方式編寫通訊程式時,通訊雙方,首先都要建立一個DatagramSocket對象,用來接收或發送資料報,然後使用DatagramPacket類對象作為傳輸資料的載體。下面看一下DatagramPacket的構造方法 :
| Constructor Summary |
DatagramPacket(byte[] buf, int length) Constructs a DatagramPacket for receiving packets of length length. |
DatagramPacket(byte[] buf, int length, InetAddress address, int port) Constructs a datagram packet for sending packets of length length to the specified port number on the specified host. |
DatagramPacket(byte[] buf, int offset, int length) Constructs a DatagramPacket for receiving packets of length length, specifying an offset into the buffer. |
DatagramPacket(byte[] buf, int offset, int length, InetAddress address, int port) Constructs a datagram packet for sending packets of length length with offset ioffsetto the specified port number on the specified host. |
DatagramPacket(byte[] buf, int offset, int length, SocketAddress address) Constructs a datagram packet for sending packets of length length with offset ioffsetto the specified port number on the specified host. |
DatagramPacket(byte[] buf, int length, SocketAddress address) Constructs a datagram packet for sending packets of length length to the specified port number on the specified host. |
可以看出,有兩個供接收的構造器和四個供發送的構造器.其中,buf中存放資料報資料,length為資料報中資料的長度,address和port旨明目的地址,offset指明了資料報的位移量。
Java組播支援
MulticastSocket 多播資料通訊端。這個組播通訊端對於收發IP多播資料包是很有用的,它擴充了DatagramSocket,在其上附加了加入internet上多播組的方法。一個多播組由D類IP地址和標準UDP連接埠指定,D類IP範圍是224.0.0.0 to 239.255.255.255,其中224.0.0.0被保留不為它用。
它有三個構造器:
| Constructor Summary |
MulticastSocket() Create a multicast socket. |
MulticastSocket(int port) Create a multicast socket and bind it to a specific port. |
MulticastSocket(SocketAddress bindaddr) Create a MulticastSocket bound to the specified socket address. |
基本上,沒有指定連接埠,只為發送,指定連接埠可收發,多址主機會用通訊端地址。
一,DatagramSocket類;DatagramPacket類;InetAddress 類
建構函式 public DatagramSocket();
public DatagramSocket(int port);
public DatagramSocket(InetAddress laddr);
close()方法
send(DatagramPacket p)
receive(DatagramPacket p)
接受方的DatagramPacket public DatagramPacket(byte[] buf, int length)
發送方的DatagramPacket public DatagramPacket(byte[] buf, int length, InetAddress address, int port
最簡單的UDP程式:
發送程式:UdpSend.java
import java.net.*;
public class UdpSend
...{
public static void main(String [] args) throws Exception
...{
DatagramSocket ds=new DatagramSocket();
String str="hello world";
DatagramPacket dp=new DatagramPacket(str.getBytes(),str.length(),
InetAddress.getByName("192.168.0.25"),3000);
ds.send(dp);
ds.close();
}
}
接收程式:UdpRecv.java
import java.net.*;
public class UdpRecv
...{
public static void main(String [] args) throws Exception
...{
DatagramSocket ds=new DatagramSocket(3000);
byte [] buf=new byte[1024];
DatagramPacket dp=new DatagramPacket(buf,1024);
ds.receive(dp);
String strRecv=new String(dp.getData(),0,dp.getLength()) +
" from " + dp.getAddress().getHostAddress()+":"+dp.getPort();
System.out.println(strRecv);
ds.close();
}
}