Java- 网络编程 简单接触UDP
Java分别为UDP和TCP两种通信协议提供了相应的编程类,这些类存放在java.net包中,与UDP对应的是DatagramSocket,与TCP对应的是ServerSocket(用于服务器端)和Socket(用于客户端);
理解
《Java就业培训》有几段话讲的很好,关于理解网络数据传递的。DatagrameSocket的就好像一个码头,DatagramePacket就好像码头的货物(包),数据传递就好像将一批货物从一个码头运到另一个码头。在运货的过程中需要指定运到哪个码头,即是所谓的IP地址。具体要运到谁手里即是加一个端口。
有一点要注意一下,DatagramePacket有下面两个构造函数,当发送数据的时候需要使用第二个构造函数,当接收数据的时候使用第1个构造函数
1.public DatagramePacket(byte[] buf,int length);
2.public DatagramePacket(byte[] buf,int length,InetAddress address,int port);
最简单的UDP程序
UdpSend:发送数据
import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; public class UdpSend{ public static void main(String[] args) throws Exception{ DatagramSocket ds = new DatagramSocket(); String str = "Hello Socket"; DatagramPacket dp = new DatagramPacket(str.getBytes(),str.length(),InetAddress.getByName("127.0.0.1"),3000); ds.send(dp); ds.close(); } }
UdpRecv:接收数据
import java.net.DatagramPacket; import java.net.DatagramSocket; public class UdpRecv{ public static void main(String[] args) throws Exception { //设置接收端口 DatagramSocket ds = new DatagramSocket(3000); byte[] bytes = new byte[1024]; DatagramPacket dp = new DatagramPacket(bytes,bytes.length); ds.receive(dp); String result = new String(dp.getData()); //result = result + " form " + dp.getAddress().getHostAddress() + " : " + dp.getPort(); System.out.println(result); ds.close(); } }
聊天小程序例子
View Code
import java.awt.*; import java.awt.event.*; import java.net.*; public class Chat { Frame f = new Frame("我的聊天室"); TextField tfIP = new TextField(15); static List lst = new List(6); static DatagramSocket ds; public Chat() { try { ds = new DatagramSocket(3000); } catch (Exception ex) { ex.printStackTrace(); } } public static void main(String[] args) { Chat chat = new Chat(); chat.init(); try { ds = new DatagramSocket(3000); } catch (Exception ex) { ex.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()) + ":from" + dp.getAddress().getHostAddress(), 0); } catch (Exception e) { e.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); ds.send(dp); } catch (Exception ex) { ex.printStackTrace(); } /* * 上面的Exception的引用变量名不能为e,而是改写成了ex,因为e已经在 * actionPerformed方法中作为形式参数变量名被定义过了。 */ ((TextField) e.getSource()).setText(""); } }); } }