黑马程序员技术交流社区

标题: 第八帖 之 UDP 整理 [打印本页]

作者: 王婷婷    时间: 2013-5-19 16:09
标题: 第八帖 之 UDP 整理
本帖最后由 王婷婷 于 2013-5-19 16:08 编辑

网络编程其实就是让计算机之间相互传输数据,网络编程也叫Socket编程。
在使计算机之间的程序相互传输数据时,这两个计算机的底层必须通过某些介质连接,这个介质就是Socket:套接字。数据在两个Socket间通过IO传输。
UDP:用户数据报协议,是一种面向无连接的协议(在向另一端发送数据的时候,不用保证另一端必须也存在,如果,另一端不存在,则将数据包丢失,若存在就将数据接收),且是一种不可靠协议(数据容易丢失)。在传输数据包前不用在两个程序间建立连接,数据包的大小要小于64k,如果要发送的数据很大,就将数据分包发送(每个数据包还是要小于64k)。因此,UDP是的传输速度很快。
数据传输是两台机器间的通信过程,所以,必须创建Socket服务(即要有发送端和接收端)。DatagramSocket可用于创建发送端和接收端的类对象。该对象提供了发送和接收的方法,既能发送数据又能接收数据。DatagramSocket构造函数中可以接收数据报包,DatagramPacket对象中可以接收指定大小的数据。
  1. <p>
  2. import java.net.*;
  3. //都是独立运行程序,有主函数</p><p>//发送端
  4. class UdpSend
  5. {
  6. public static void main(String[] args)  throws Exception
  7. {
  8. //建立UDP socket服务,
  9. DatagramSocket ds = new DatagramSocket();</p><p> //确定数据,并将数据封装成数据包                目的端口号
  10.        //DatagramPacket(byte[] buf, int length, InetAddress address, int port)
  11.    // 将字符串数据转换成字节数组
  12. byte[] buf = "发送的数据为:".getBytes();
  13. //将要发送的数据、数据长度、接收的机器地址和该机器的应用程序,作为参数传递给DatagramPacket
  14. DatagramPacket dp =      
  15.   new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.100"),10000);</p><p> //通过socket服务,将已有数据包发送出去。通过send方法
  16. ds.send(dp);</p><p> //关闭资源
  17. ds.close();</p><p> //运行后在控制台无数据,因为UDP是面向无连接的,,数据丢失。。接收端未开启
  18. }
  19. }</p><p>//接收端</p><p>class UdpReceive
  20. {
  21. public static void main(String[] args) throws Exception
  22. {
  23. //创建udp socket ,既能发送又能接收  建立端点
  24. DatagramSocket ds = new DatagramSocket(1000);</p><p> //定义数据包,用于存储数据   数据包对象中已经定义了功能提取字节数据中的不同数据信息
  25. byte[] buf = new byte[1024];
  26. DatagramPacket dp = new DatagramPacket(buf,buf.length);</p><p> //通过socket服务中的receive方法存入数据
  27. ds.receive(dp);//阻塞式方法    没数据 就等待 线程机制</p><p> //通过数据包的方法获取其中数据    获取地址并得到字符串(返回的是对象)
  28. String ip = dp.getAddress().getHostAddress();
  29. //截取一部分(0,dp.length)
  30. String data = new String(dp.getData(),0,dp.getLength());
  31. int port = dp.getPort();</p><p> System.out.println(ip+"---"+data+"----"+port);</p><p> //关闭资源
  32. ds.close();
  33. }
  34. }</p><p>class UdpDemo
  35. {
  36. public static void main(String[] args)
  37. {
  38.   /*
  39.   开启两个cmd命令行,可以将发送端和接收端中的任意一个作为发送或接收方</p><p>  */
  40. }
  41. }

  42. </p>
复制代码
键盘录入:也就是可以将键盘输入的数据打包发送给接收端。

  1. import java.net.*;
  2. import java.io.*;
  3. class  UdpSend2
  4. {
  5.         public static void main(String[] args) throws Exception
  6.         {
  7.                 //创建udp socket服务,建立端点
  8.                 DatagramSocket ds = new DatagramSocket();

  9.                 //确定要发送的数据  
  10.                 //由于要发送的数据是键盘录入的内容,所以,使用到了IO流
  11.                 BufferedReader bufr =
  12.                         new BufferedReader(new InputStreamReader(System.in));
  13.                 String line = null;
  14.                 while ((line=bufr.readLine())!=null)   //read 也是阻塞式方法  所以 发送端和接收端都等待
  15.                 {
  16.                         if ("再聊---".equals(line))
  17.                                 break;
  18.                         byte[] buf = line.getBytes();

  19.                         //将键盘录入的数据封装成数据包
  20.                         DatagramPacket dp =
  21.                                 new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.103"),10001);
  22.                        
  23.                         //将封装好的数据包发送出去
  24.                         ds.send(dp);
  25.                 }
  26.                 ds.close();
  27.         }
  28. }

  29. class UdpReceive2
  30. {
  31.         public static void main(String[] args) throws Exception
  32.         {
  33.                 //建立udp socket服务
  34.                 DatagramSocket ds = new DatagramSocket();

  35.                 //定义数据包,用于存储接收的数据
  36.                 //接收的是键盘录入的数据,所以发送端发送多少,接收端就接收多少
  37.                 while (true)
  38.                 {
  39.                         //定义字节数组,用于存储数据,若数据较大 大小可 1024x64
  40.                         byte[] buf = new byte[1024];
  41.                        
  42.                         //将接收的数据存储到数据包中,
  43.                         DatagramPacket dp = new DatagramPacket(buf,buf.length);

  44.                         ds.receive(dp);
  45.                        
  46.                         //获取ip地址和传送过来的数据
  47.                         String ip = dp.getAddress().getHostAddress();
  48.                         String data = new String (dp.getData(),0,dp.getLength());

  49.                         System.out.println(ip+"----"+data);
  50.                 }
  51.                 //不必关闭资源  若关掉 那么其他端口就发送的内容就接收不到

  52.         }
  53. }
复制代码

作者: 王婷婷    时间: 2013-5-19 16:22
UDP一般使用于即时通信,如QQ聊天,视频会议等,这些对于数据的准确性和丢包要求比较低,但速度要求要快。
编写一个简单的聊天小程序,一个负责接收数据,一个负责发送数据,还要保证两个部分同时执行,则使用多线程。
一个线程控制接收,一个线程控制发送。接收和发送动作不一致,所以定义两个run方法,用于编写接收端和发送端的代码
且这两个方法要封装到两个不同的类中
  1. import java.io.*;
  2. import java.net.*;
  3. //实现Runnable接口
  4. class Send implements Runnable
  5. {
  6.         private DatagramSocket ds;
  7.         public Send(DatagramSocket ds)
  8.         {
  9.                 this.ds = ds;
  10.         }
  11.         //复写run方法
  12.         public void run()
  13.         {
  14.                 try
  15.                 {
  16.                         //创建字符流缓冲区对象,用于接收键盘录入的数据
  17.                         BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));

  18.                         String line = null;
  19.                         //接收键盘录入的数据,如果键盘录入未停止,就将键盘录入的数据先存储在数据包中
  20.                          while ((line=bufr.readLine())!=null)
  21.                          {
  22.                                  //如果键盘录入的数据为886,那么跳出循环,不在录入
  23.                                  if ("886".equals(line))
  24.                                          break;

  25.                                 //否则,将键入的数据转换成字节数据存储到字节数组中
  26.                                  byte[] buf = line.getBytes();
  27.                                
  28.                                 //将数据(包括键盘录入的数据、数据的长度接收的地址)封装到DatagramPacket对象中,等待发送
  29.                                  DatagramPacket dp =
  30.                                          new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.109"),10009);   //,,,103
  31.                                  //调用Socket服务的send方法,将数据报包发送出去
  32.                                  ds.send(dp);
  33.                          }
  34.                 }
  35.                 catch (Exception e)
  36.                 {
  37.                         //若发生异常,直接抛出运行时异常,迫使程序停止
  38.                         throw new RuntimeException("发送失败");
  39.                 }
  40.         }
  41. }

  42. class Receive implements Runnable
  43. {
  44.         private DatagramSocket ds;
  45.         public Receive(DatagramSocket ds)
  46.         {
  47.                 this.ds = ds;
  48.         }
  49.         public void run()
  50.         {
  51.                 try
  52.                 {
  53.                         //如果
  54.                         while (true)
  55.                         {
  56.                                 //定义一个字节数组,用于存储发送端发送过来的数据
  57.                                 byte[] buf = new byte[1024];
  58.                                 DatagramPacket dp = new DatagramPacket(buf,buf.length);
  59.                             
  60.                                 ds.receive(dp);

  61.                                 String ip = dp.getAddress().getHostAddress();
  62.                                 //这里接收的是缓冲区的字节数组数据长度
  63.                                 String data = new String(dp.getData(),0,dp.getLength());
  64.                                 System.out.println(ip+"----"+data);

  65.                         }

  66.                 }
  67.                 catch (Exception e)
  68.                 {
  69.                         throw new RuntimeException("发送失败");
  70.                 }
  71.                
  72.         }
  73. }

  74. class  ChatDemo
  75. {
  76.         public static void main(String[] args) throws Exception
  77.         {
  78.                 DatagramSocket sendSocket = new DatagramSocket();
  79.                 DatagramSocket receiveSocket = new DatagramSocket(10009);
  80.                 //开启线程
  81.                 new Thread(new Send(sendSocket)).start();
  82.                 new Thread(new Receive(receiveSocket)).start();
  83.         }
  84. }
复制代码

作者: 神之梦    时间: 2013-5-19 16:23
楼主犀利{:soso_e179:}
作者: 王安琪    时间: 2013-5-27 15:12
王婷婷 发表于 2013-5-19 16:22
UDP一般使用于即时通信,如QQ聊天,视频会议等,这些对于数据的准确性和丢包要求比较低,但速度要求要快。
...

应该是楼主求认识:L




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2