Posted on 2007-04-20 22:50
chenweicai 阅读(897)
评论(0) 编辑 收藏
-
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();
}
}