zoukankan      html  css  js  c++  java
  • UDP通讯协议

    常见的通讯协议有udp和tcp。

    先来简单了解一下这两个协议各自的特点:

    UDP:

    --将数据及源、目的封装在数据包中,不需要建立连接;

    --每个数据包的大小限制在64k以内;

    --因无连接,是不可靠协议;

    --不需要建立连接,所以传输速度快,但是容易丢失数据;

    总之:Udp是面向无连接的通讯协议,传输数据时,不管对端服务是否启动,直接发送。

    日常中使用Udp技术的软件有:飞秋、视频会议等;

    TCP:

    --建立连接,形成传输数据的通道;

    --在连接中进行大的数据量传输;

    --通过三次握手完成连接,是可靠协议;

    --必须建立连接,效率会稍低;

    日常中使用Tcp技术的软件有:打电话的场景,下载。

    了解了以上两种常用的通讯协议之后,再认识一下网络通讯的机制:Socket  

    Socket:

    --就是为网络服务提供的一种机制;

    --通信的两端都有Socket;

    --网络通信其实就是Socket建的通信;

    --数据再两个Socket间通过 IO 传输。

    也可以这样理解:Socket就像连接航线两端的港口。

    ============================优雅的分割线============================

    我们在实现网络编程时,最重要的是要理解并掌握其实现的原理:

    下面先讲解一下Udp传输的原理:

    --1、Udp传输技术基于 DatagramSocket 与 DatagramPacket对象;

    --2、建立发送端、接收端;

    --3、建立数据包;

    --4、调用Socket的发送接收方法;

    --5、关闭Socket;

    --6、发送端和接收端是两个独立的运行程序;

    下面来看一个简单Udp传输Demo:

    //发送端:

    package com.shindo.java.udp;
    
    import java.net.*;
    
    /**
     * 需求:通过Udp传输方式,将一段文字数据发送 出去;
     * 
     * 思路:
     * 1、建立UdpSocket服务;
     * 2、提供数据,并将数据封装到数据包中;
     * 3、通过Socket服务的发送功能,将数据包发出去
     * 4、关闭资源
     */
    public class UdpSend {
        public static void main(String[] args)throws Exception{
            //1、创建Udp服务,通过DatagramSocket对象
            DatagramSocket ds = new DatagramSocket();
            
            //2、确定数据,并封装成数据包
            byte[] buf = "This's UdpSend test first Demo".getBytes();
            
            /*DatagramPacket(byte[] buf, int length, InetAddress address, int port) 
                  构造数据报包,用来将长度为 length 的包发送到指定主机上的指定端口号。
             */
             DatagramPacket dp = new DatagramPacket(buf,buf.length,InetAddress.getByName("127.0.0.1"),11010);
             
             //3、通过Socket服务,将已有的数据包发送出去,通过send方法
             ds.send(dp);
             
             Thread.sleep(10000);
             //4、关闭资源
             ds.close();
        }
    }
    View Code

    //接收端:

    package com.shindo.java.udp;
    import java.net.*;
    /**
     * 需求:定义一个应用程序,用于接收Udp协议传输的数据并处理
     * 
     * 思路:
     * 1、定义UdpSocket服务,并监听一个端口;
     * 2、定义个数据包,因为要存储接收到的字节数据--数据包对象中封装了提取字节数据信息的方法;
     * 3、通过Socket服务的receive方法将收到的数据存入已定义好的数据包中;
     * 4、通过数据包对象的特有功能,将这些不同的数据去除,打印在控制台上;
     * 5、关闭资源
     */
    public class Udpreceive {
        public static void main(String[] args)throws Exception{
            //创建UdpSocket,建立端点
            DatagramSocket ds = new DatagramSocket(11010);
            
            while(true){
                //2、定义数据包用于存储数据
                byte[] buf = new byte[1024];
                /*
                 * DatagramPacket(byte[] buf, int length) 
                      构造 DatagramPacket,用来接收长度为 length 的数据包。
                 */
                DatagramPacket dp = new DatagramPacket(buf,buf.length);
                
                //3、通过数服务的receive方法,将收到的数据存入数据包中
                ds.receive(dp);
                
                //4、通过数据包的方法获取其中的数据
                String ip = dp.getAddress().getHostAddress();
                System.out.println(ip + "..........is connected");
                String data = new String(dp.getData(),0,dp.getLength());//只打印接收数据的长度,不打印全部缓冲流
                System.out.println(data);
                int port = dp.getPort();
                System.out.println("port:" + port);
                
                //5、关闭资源
                ds.close();
            }
        }
    }
    View Code

    运行结果:

    127.0.0.1..........is connected
    This's UdpSend test first Demo
    port:52793
    Exception in thread "main" java.net.SocketException: Socket closed
        at java.net.PlainDatagramSocketImpl.receive0(Native Method)
        at java.net.PlainDatagramSocketImpl.receive(PlainDatagramSocketImpl.java:136)
        at java.net.DatagramSocket.receive(DatagramSocket.java:725)
        at com.shindo.java.udp.Udpreceive.main(Udpreceive.java:28)

    ============================优雅的分割线============================

    上面的Demo我们可以看到只是实现了简单的客户端发送,服务端读取并展示的过程。而且客户端只能发送特定的内容:This's UdpSend test first Demo

    我们下面就把客户端改写一下,让它能够读取键盘录入的信息:

    //发送端:使用键盘录入信息

    package com.shindo.java.udp;
    import java.io.*;
    import java.net.*;
    /**
     * 需求:实现发送信息的键盘录入
     */
    public class UdpSendKeyboard {
        public static void main(String[] args) throws Exception{
            DatagramSocket ds = new DatagramSocket();
            BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
            String line = null;
            while((line = bufr.readLine()) != null ){
                if("byebye".equals(line)) break;
                
                byte[] buf = line.getBytes();
                DatagramPacket dp = new DatagramPacket(buf,buf.length,InetAddress.getByName("127.0.0.1"),11010);
                
                ds.send(dp);
            }
            ds.close();
        }
    }
    View Code
  • 相关阅读:
    linux学习资料收藏
    java 自动补全
    iframe
    XSLT 创建CDATA节点
    java 线程
    SQL(ORACLE)
    ubuntu下php无法载入mysql扩展
    Laravel 5.2 新特性系列 —— 多用户认证功能实现详解
    Windows环境下的NodeJS+NPM+Bower安装配置步骤
    关于Laravel 5 中 Html,Form 安装以及修改使用标签
  • 原文地址:https://www.cnblogs.com/shindo/p/5296713.html
Copyright © 2011-2022 走看看