-
public class DatagramSocket
- extends Object
此類表示用來發送和接收數據報包的套接字。
數據報套接字是包投遞服務的發送或接收點。每個在數據報套接字上發送或接收的包都是單獨編址和路由的。從一臺機器發送到另一臺機器的多個包可能選擇不同的路由,也可能按不同的順序到達。
在 DatagramSocket 上總是啟用 UDP 廣播發送。為了接收廣播包,應該將 DatagramSocket 綁定到通配符地址。在某些實現中,將 DatagramSocket 綁定到一個更加具體的地址時廣播包也可以被接收。
示例:DatagramSocket s = new DatagramSocket(null); s.bind(new InetSocketAddress(8888));
這等價于:DatagramSocket s = new DatagramSocket(8888);
兩個例子都能創建能夠在 UDP 8888 端口上接收廣播的 DatagramSocket。
-
public final class DatagramPacket
- extends Object
此類表示數據報包。
數據報包用來實現無連接包投遞服務。每條報文僅根據該包中包含的信息從一臺機器路由到另一臺機器。從一臺機器發送到另一臺機器的多個包可能選擇不同的路由,也可能按不同的順序到達。不對包投遞做出保證。
給個具體實現的例子
//UDP數據的發送類似發送尋呼一樣的道理。就像尋呼機必須先處于開機接收狀態才能接收尋呼一樣的道理
//我們先要運行UDP接收程序,再運行UDP發送程序。UDP數據包的接收是過期作廢的。
public class UdpSend {
public static void main(String[] args) throws SocketException, UnknownHostException{
DatagramSocket ds = new DatagramSocket();//創建用來發送數據報包的套接字
String str = "Hello World,陳偉才";
DatagramPacket dp = new DatagramPacket(str.getBytes(), str.getBytes().length,
InetAddress.getByName("10.214.16.80"), 3000);
//構造數據報包,用來將長度為 length 的包發送到指定主機上的指定端口號
try {
ds.send(dp);
} catch (IOException e) {
e.printStackTrace();
}
ds.close();
}
}
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();
}
}
再給個例子Chat
public class Chat {
Frame f = new Frame("我的聊天室");
/*
* tfIp 是用于輸入IP地址的文本框,在發送數據時, 要取出其中的IP地址,
* 所以將其定義成員變量,以便發送消息的程序代碼能訪問。
*/
TextField tfIP = new TextField(15);
/**
* lst時用于顯示接收消息的列表框, 在接收到數據時,要向其中增加新的記錄項
* 所以將其定義成員變量,以便發送消息的程序代碼能訪問
*/
List lst = new List(6);
DatagramSocket ds;
public Chat(){
try{
ds = new DatagramSocket(3000);
}catch(Exception e){
e.printStackTrace();
}
new Thread (new Runnable(){
public void run(){
byte[] buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf, 1024);
while (true){
try{
ds.receive(dp);
lst.add(new String(buf, 0 , dp.getLength()) +
" : form " + dp.getAddress().getHostAddress(), 0);
}catch(Exception ee){
ee.printStackTrace();
}
}
}
}).start();
}
public void init(){
f.setSize(300, 300);
f.add(lst);
Panel p = new Panel();
p.setLayout(new BorderLayout());
p.add("West", tfIP);
TextField tfData = new TextField (20);
p.add("East", tfData);
f.add("South", p);
f.setVisible(true);
f.setResizable(false);//不能改變窗口大小
//增加關閉窗口的事件處理代碼
f.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
ds.close();//程序退出時,關閉Socket,釋放相關的資源
f.setVisible(false);
f.dispose();
System.exit(0);
}
});
//增加在消息文本框中按下回車鍵的事件處理代碼
tfData.addActionListener(new ActionListener(){
public void actionPerformed (ActionEvent e){
//要在這里增加網絡消息發送相關程序代碼
//下面的語句用于數據發送后,清空文本框中原來的內容
// 取出文本框的消息字符串,并將其轉換成字節數組
byte[] buf;
buf = e.getActionCommand().getBytes();
try {
DatagramPacket dp = new DatagramPacket(buf, buf.length,
InetAddress.getByName(tfIP.getText()), 3000);
try {
ds.send(dp);
} catch (IOException e1) {
e1.printStackTrace();
}
} catch (UnknownHostException e1) {
e1.printStackTrace();
}
((TextField)e.getSource()).setText("");
}
});
}
public static void main(String[] args){
Chat chat = new Chat();
chat.init();
}
}