黑马程序员技术交流社区
标题: 第八帖 之 UDP 整理 [打印本页]
作者: 王婷婷 时间: 2013-5-19 16:09
标题: 第八帖 之 UDP 整理
本帖最后由 王婷婷 于 2013-5-19 16:08 编辑
网络编程其实就是让计算机之间相互传输数据,网络编程也叫Socket编程。
在使计算机之间的程序相互传输数据时,这两个计算机的底层必须通过某些介质连接,这个介质就是Socket:套接字。数据在两个Socket间通过IO传输。
UDP:用户数据报协议,是一种面向无连接的协议(在向另一端发送数据的时候,不用保证另一端必须也存在,如果,另一端不存在,则将数据包丢失,若存在就将数据接收),且是一种不可靠协议(数据容易丢失)。在传输数据包前不用在两个程序间建立连接,数据包的大小要小于64k,如果要发送的数据很大,就将数据分包发送(每个数据包还是要小于64k)。因此,UDP是的传输速度很快。
数据传输是两台机器间的通信过程,所以,必须创建Socket服务(即要有发送端和接收端)。DatagramSocket可用于创建发送端和接收端的类对象。该对象提供了发送和接收的方法,既能发送数据又能接收数据。DatagramSocket构造函数中可以接收数据报包,DatagramPacket对象中可以接收指定大小的数据。
- <p>
- import java.net.*;
- //都是独立运行程序,有主函数</p><p>//发送端
- class UdpSend
- {
- public static void main(String[] args) throws Exception
- {
- //建立UDP socket服务,
- DatagramSocket ds = new DatagramSocket();</p><p> //确定数据,并将数据封装成数据包 目的端口号
- //DatagramPacket(byte[] buf, int length, InetAddress address, int port)
- // 将字符串数据转换成字节数组
- byte[] buf = "发送的数据为:".getBytes();
- //将要发送的数据、数据长度、接收的机器地址和该机器的应用程序,作为参数传递给DatagramPacket
- DatagramPacket dp =
- new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.100"),10000);</p><p> //通过socket服务,将已有数据包发送出去。通过send方法
- ds.send(dp);</p><p> //关闭资源
- ds.close();</p><p> //运行后在控制台无数据,因为UDP是面向无连接的,,数据丢失。。接收端未开启
- }
- }</p><p>//接收端</p><p>class UdpReceive
- {
- public static void main(String[] args) throws Exception
- {
- //创建udp socket ,既能发送又能接收 建立端点
- DatagramSocket ds = new DatagramSocket(1000);</p><p> //定义数据包,用于存储数据 数据包对象中已经定义了功能提取字节数据中的不同数据信息
- byte[] buf = new byte[1024];
- DatagramPacket dp = new DatagramPacket(buf,buf.length);</p><p> //通过socket服务中的receive方法存入数据
- ds.receive(dp);//阻塞式方法 没数据 就等待 线程机制</p><p> //通过数据包的方法获取其中数据 获取地址并得到字符串(返回的是对象)
- String ip = dp.getAddress().getHostAddress();
- //截取一部分(0,dp.length)
- String data = new String(dp.getData(),0,dp.getLength());
- int port = dp.getPort();</p><p> System.out.println(ip+"---"+data+"----"+port);</p><p> //关闭资源
- ds.close();
- }
- }</p><p>class UdpDemo
- {
- public static void main(String[] args)
- {
- /*
- 开启两个cmd命令行,可以将发送端和接收端中的任意一个作为发送或接收方</p><p> */
- }
- }
- </p>
复制代码键盘录入:也就是可以将键盘输入的数据打包发送给接收端。
- import java.net.*;
- import java.io.*;
- class UdpSend2
- {
- public static void main(String[] args) throws Exception
- {
- //创建udp socket服务,建立端点
- DatagramSocket ds = new DatagramSocket();
- //确定要发送的数据
- //由于要发送的数据是键盘录入的内容,所以,使用到了IO流
- BufferedReader bufr =
- new BufferedReader(new InputStreamReader(System.in));
- String line = null;
- while ((line=bufr.readLine())!=null) //read 也是阻塞式方法 所以 发送端和接收端都等待
- {
- if ("再聊---".equals(line))
- break;
- byte[] buf = line.getBytes();
- //将键盘录入的数据封装成数据包
- DatagramPacket dp =
- new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.103"),10001);
-
- //将封装好的数据包发送出去
- ds.send(dp);
- }
- ds.close();
- }
- }
- class UdpReceive2
- {
- public static void main(String[] args) throws Exception
- {
- //建立udp socket服务
- DatagramSocket ds = new DatagramSocket();
- //定义数据包,用于存储接收的数据
- //接收的是键盘录入的数据,所以发送端发送多少,接收端就接收多少
- while (true)
- {
- //定义字节数组,用于存储数据,若数据较大 大小可 1024x64
- byte[] buf = new byte[1024];
-
- //将接收的数据存储到数据包中,
- DatagramPacket dp = new DatagramPacket(buf,buf.length);
- ds.receive(dp);
-
- //获取ip地址和传送过来的数据
- String ip = dp.getAddress().getHostAddress();
- String data = new String (dp.getData(),0,dp.getLength());
- System.out.println(ip+"----"+data);
- }
- //不必关闭资源 若关掉 那么其他端口就发送的内容就接收不到
- }
- }
复制代码
作者: 王婷婷 时间: 2013-5-19 16:22
UDP一般使用于即时通信,如QQ聊天,视频会议等,这些对于数据的准确性和丢包要求比较低,但速度要求要快。
编写一个简单的聊天小程序,一个负责接收数据,一个负责发送数据,还要保证两个部分同时执行,则使用多线程。
一个线程控制接收,一个线程控制发送。接收和发送动作不一致,所以定义两个run方法,用于编写接收端和发送端的代码
且这两个方法要封装到两个不同的类中- import java.io.*;
- import java.net.*;
- //实现Runnable接口
- class Send implements Runnable
- {
- private DatagramSocket ds;
- public Send(DatagramSocket ds)
- {
- this.ds = ds;
- }
- //复写run方法
- public void run()
- {
- try
- {
- //创建字符流缓冲区对象,用于接收键盘录入的数据
- BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
- String line = null;
- //接收键盘录入的数据,如果键盘录入未停止,就将键盘录入的数据先存储在数据包中
- while ((line=bufr.readLine())!=null)
- {
- //如果键盘录入的数据为886,那么跳出循环,不在录入
- if ("886".equals(line))
- break;
- //否则,将键入的数据转换成字节数据存储到字节数组中
- byte[] buf = line.getBytes();
-
- //将数据(包括键盘录入的数据、数据的长度接收的地址)封装到DatagramPacket对象中,等待发送
- DatagramPacket dp =
- new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.109"),10009); //,,,103
- //调用Socket服务的send方法,将数据报包发送出去
- ds.send(dp);
- }
- }
- catch (Exception e)
- {
- //若发生异常,直接抛出运行时异常,迫使程序停止
- throw new RuntimeException("发送失败");
- }
- }
- }
- class Receive implements Runnable
- {
- private DatagramSocket ds;
- public Receive(DatagramSocket ds)
- {
- this.ds = ds;
- }
- public void run()
- {
- try
- {
- //如果
- while (true)
- {
- //定义一个字节数组,用于存储发送端发送过来的数据
- byte[] buf = new byte[1024];
- DatagramPacket dp = new DatagramPacket(buf,buf.length);
-
- ds.receive(dp);
- String ip = dp.getAddress().getHostAddress();
- //这里接收的是缓冲区的字节数组数据长度
- String data = new String(dp.getData(),0,dp.getLength());
- System.out.println(ip+"----"+data);
- }
- }
- catch (Exception e)
- {
- throw new RuntimeException("发送失败");
- }
-
- }
- }
- class ChatDemo
- {
- public static void main(String[] args) throws Exception
- {
- DatagramSocket sendSocket = new DatagramSocket();
- DatagramSocket receiveSocket = new DatagramSocket(10009);
- //开启线程
- new Thread(new Send(sendSocket)).start();
- new Thread(new Receive(receiveSocket)).start();
- }
- }
复制代码
作者: 神之梦 时间: 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 |