zoukankan      html  css  js  c++  java
  • 详解 DatagramSocket类

    (请观看本人博文 —— 《详解 网络编程》)


    DatagramSocket

    概述

    这类代表一个发送和接收数据包插座
    该类是遵循 UDP协议 实现的一个Socket类
    数据报套接字发送或者接收点的分组传送服务。
    每个发送的数据包或数据报套接字上接收单独寻址和路由。
    从一台机器发送到另一台机器的多个数据包可能会被不同的路由,
    并可以以任何顺序到达。
    在可能的情况下,
    一个新建的DatagramSocket有SO_BROADCAST套接字选项已启用,以便允许广播数据报传输。
    为了收到广播包应该将DatagramSocket绑定到通配符地址。
    在一些实施方案中,广播包,也可以接受当一个DatagramSocket绑定到一个更具体的地址。


    现在,本人来展示下这个类的构造方法
    构造方法

    • DatagramSocket()
      构建一个数据报套接字 ,绑定到本地主机任何可用的端口
    • DatagramSocket(int port)
      构建一个数据报套接字,绑定到本地主机指定端口
    • DatagramSocket(int port, InetAddress laddr)
      创建一个数据报套接字,绑定到指定的本地地址
    • DatagramSocket(SocketAddress bindaddr)
      创建一个数据报套接字,绑定到指定的本地套接字地址
    • protected DatagramSocket(DatagramSocketImpl impl)
      创建一个绑定的数据报套接字, 与指定的datagramsocketimpl相关(一般不使用)

    那么,现在,本人来展示下这个类的API
    API

    • InetAddress getInetAddress()
      返回此套接字连接的地址
    • InetAddress getLocalAddress()
      获取绑定的套接字的本地地址
    • int getLocalPort()
      返回此套接字绑定的本地主机上的端口号
    • SocketAddress getLocalSocketAddress()
      返回此套接字绑定到的端点的地址
    • int getPort()
      返回此套接字连接的端口号
    • void close()
      关闭该数据报套接字
    • void connect(InetAddress address, int port)
      将套接字连接到这个套接字的远程地址
    • void connect(SocketAddress addr)
      将此套接字连接到远程套接字地址(IP地址+端口号)
    • void bind(SocketAddress addr)
      结合这个DatagramSocket到特定的地址和端口
    • void disconnect()
      断开插座
    • boolean getBroadcast()
      如果so_broadcast启用
    • DatagramChannel getChannel()
      返回与此数据报套接字相关的独特的 DatagramChannel对象,如果任何
    • int getReceiveBufferSize()
      得到这个 DatagramSocket的so_rcvbuf期权价值,即通过平台用于该 DatagramSocket输入缓冲区的大小。
    • SocketAddress getRemoteSocketAddress()
      返回此套接字连接的端点的地址,或如果它是无关的 null。
    • boolean getReuseAddress()
      如果so_reuseaddr启用。
    • int getSendBufferSize()
      得到这个 DatagramSocket的so_sndbuf期权价值,即缓冲区的大小由平台用于输出在这 DatagramSocket。
    • int getSoTimeout()
      检索设置so_timeout。
    • int getTrafficClass()
      获取交通类或类型的服务在IP数据报头的DatagramSocket发送的数据包。
    • boolean isBound()
      返回套接字的绑定状态。
    • boolean isClosed()
      返回套接字是否关闭或不关闭的。
    • boolean isConnected()
      返回套接字的连接状态。
    • void receive(DatagramPacket p)
      接收数据报包从这个插座。
    • void send(DatagramPacket p)
      从这个套接字发送数据报包。
    • void setBroadcast(boolean on)
      启用/禁用so_broadcast。
    • static void setDatagramSocketImplFactory(DatagramSocketImplFactory fac)
      集的数据报套接字实现工厂的应用。
    • void setReceiveBufferSize(int size)
      集so_rcvbuf选项,这 DatagramSocket指定值。
    • void setReuseAddress(boolean on)
      启用/禁用so_reuseaddr套接字选项。
    • void setSendBufferSize(int size)
      集so_sndbuf选项,这 DatagramSocket指定值。
    • void setSoTimeout(int timeout)
      启用/禁用so_timeout以指定的超时时间,以毫秒为单位。
    • void setTrafficClass(int tc)
      集交通类或从这个DatagramSocket发送数据报的IP数据报头字节型服务

    那么,接下来,本人来通过一个例子,来展示下部分API的使用
    例1

    题目
    右转哥忽然被竖锯附体,透过屏幕看向了一个未关注右转哥的同学,现在,他俩之间要进行一轮对话,请完成相关代码。
    要求
    使用DatagramSocket类构造对象,实现下右转哥(竖锯附身版)和那位同学的对话

    那么,本人来给出代码:

    首先是右转哥的代码:

    package edu.youzg.about_net.about_udp.core;
    
    import java.io.IOException;
    import java.net.*;
    
    public class UDPYouzg {
    
        public static void main(String[] args) throws IOException {
            //创建Youzg 的 UDP的Socket
            DatagramSocket youzg = new DatagramSocket(8888);
    
            //封装数据   DatagramPacket数据报包 数据报包用来实现无连接包投递服务。
            byte[] bytes = "Hello,Students who don't pay attention to Youzg
    I want to play a game...".getBytes();
            DatagramPacket packet = new DatagramPacket(bytes, bytes.length, InetAddress.getLocalHost(), 6666);
    
            //发送数据,发送数据报包
            youzg.send(packet);
    
            //接收数据
            youzg.receive(packet); //阻塞的方法,如果数据没过来,就等待在这里。
            //从数据报包中取数据
            byte[] data = packet.getData();
            //获取数据报包中数据的实际长度
            int length = packet.getLength();
            //把字节数据转换成字符串
            String s = new String(data, 0, length);
            System.out.println("the guy 给你发来消息,内容是:
    " + s);
    
            //释放资源
            youzg.close();
        }
    
    }
    

    接下来实现下 该同学的代码:

    package edu.youzg.about_net.about_udp.core;
    
    import java.io.IOException;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetAddress;
    
    public class UDPYou {
    
        public static void main(String[] args) throws IOException {
            //创建数据报套接字并将其绑定到本地主机上的指定端口。
            //创建服务端的Sokcet并暴露端口号
            DatagramSocket you = new DatagramSocket(6666);
    
            //构造 DatagramPacket,用来接收长度为 length 的数据包。
            byte[] bytes = new byte[1024];
            DatagramPacket packet = new DatagramPacket(bytes, bytes.length);
    
            //接收数据
            you.receive(packet); //阻塞的方法,如果数据没过来,就等待在这里。
            //从数据报包中取数据
            byte[] data = packet.getData();
            //获取数据报包中数据的实际长度
            int length = packet.getLength();
            //把字节数据转换成字符串
            String s = new String(data, 0, length);
            System.out.println("Jigsaw 给你发来消息,内容是:
    " + s);
    
            //回复消息
            data = "I'm sorry,I'm following Youzg right now at thumb up".getBytes();
            packet = new DatagramPacket(data, data.length, InetAddress.getLocalHost(), 8888);
            you.send(packet);
    
            //释放资源
            you.close();
        }
    
    }
    

    那么,现在,本人来展示下两人的对话过程(运行结果):

    首先是 该同学 接受到信息:
    在这里插入图片描述

    接下来是 右转哥 接收到的回复:
    在这里插入图片描述
    可以看到,上述代码实现了两人的一问一答的对话。
    (哈哈,看到上述的聊天过程,右转哥不禁笑出了声)

    例2:

    题目
    右转哥自从被附体之后,在无意中做了很多自己并不知道的事情,所以,他要和有的同学进行一系列交谈,了解当时发生的事。请用代码实现下他们的聊天。
    要求
    编写模拟聊天室的聊天功能,在控制台输入语句,在控制台显示接收到的语句

    那么,本人现在来展示下代码:
    首先是 右转哥聊天所需的代码:

    package edu.youzg.about_net.about_udp.core;
    
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.net.*;
    
    public class UDPYouzg {
    
        public static void main(String[] args) throws IOException {
            //创建子线程开启服务器,来接收消息
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        //创建服务端的Socket,并暴露端口号
                        DatagramSocket ds = new DatagramSocket(8888);
                        System.out.println("Youzg服务器已经开启,等待连接");
                        while (true) {
                            //接收发送过来的数据
                            byte[] bytes = new byte[1024];
                            DatagramPacket dp = new DatagramPacket(bytes, bytes.length);
    
                            ds.receive(dp);
                            //从数据报包中取出数据
                            byte[] data = dp.getData();
                            int length = dp.getLength();
                            //取发送者的IP
                            String s = new String(data, 0, length);
                            System.out.println("the gay:" + s);
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }).start();
    
    
            //在主线程给对方发消息
            sendMsg();
    
        }
    
        private static void sendMsg() {
            try {
                //创建客户端的socket
                DatagramSocket ds = new DatagramSocket();
                //创建键盘录入对象
                BufferedReader bfr = new BufferedReader(new InputStreamReader(System.in));
                while (true) {
                    System.out.println("请输入要发送消息:");
                    String s = bfr.readLine();
                    if (s.equals("byebye")) {
                        break;
                    }
                    byte[] bytes = s.getBytes();
                    //创建数据报包
                    DatagramPacket dp = new DatagramPacket(bytes, bytes.length, InetAddress.getLocalHost(), 9999);
                    //发送数据
                    ds.send(dp);
                }
    
                //释放资源
                ds.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
    }
    

    接下来是 那位同学聊天所需的代码:

    package edu.youzg.about_net.about_udp.core;
    
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetAddress;
    
    public class UDPYou {
    
        public static void main(String[] args) throws IOException {
            //创建子线程开启服务器,来接收消息
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        //创建服务端的Socket,并暴露端口号
                        DatagramSocket ds = new DatagramSocket(9999);
                        System.out.println("the guy 服务器已经开启,等待连接");
                        while (true) {
                            //接收发送过来的数据
                            byte[] bytes = new byte[1024];
                            DatagramPacket dp = new DatagramPacket(bytes, bytes.length);
    
                            ds.receive(dp);
                            //从数据报包中取出数据
                            byte[] data = dp.getData();
                            int length = dp.getLength();
                            //取发送者的IP
                            String s = new String(data, 0, length);
                            System.out.println("Youzg:" + s);
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }).start();
    
    
            //在主线程给对方发消息
            sendMsg();
    
        }
    
        private static void sendMsg() {
            try {
                //创建客户端的socket
                DatagramSocket ds = new DatagramSocket();
                //创建键盘录入对象
                BufferedReader bfr = new BufferedReader(new InputStreamReader(System.in));
                while (true) {
                    System.out.println("请输入要发送消息:");
                    String s = bfr.readLine();
                    if (s.equals("byebye")) {
                        break;
                    }
                    byte[] bytes = s.getBytes();
                    //创建数据报包
                    DatagramPacket dp = new DatagramPacket(bytes, bytes.length, InetAddress.getLocalHost(), 8888);
                    //发送数据
                    ds.send(dp);
                }
    
                //释放资源
                ds.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
    }
    

    那么,现在,本人来展示下聊天内容(运行结果):

    首先是右转哥的聊天记录:
    在这里插入图片描述
    接下来是那位同学的聊天记录:
    在这里插入图片描述
    可以看到,在byebye前的对话都传达了!


    (本人 网络编程 总集篇博文链接:https://www.cnblogs.com/codderYouzg/p/12419011.html)

  • 相关阅读:
    MyBatis(第三方缓存整合原理&ehcache适配包下载)
    MyBatis(缓存机制)
    MyBatis(动态SQL2)
    MyBatis(动态SQL)
    MyBatis(映射文件中使用foreach标签时报错,属性collection的问题)
    MyBatis映射文件(编写SQL语句;可有可无(无的时候,使用注解编程))
    Python virtualenv with Sublime Text 3
    python & mongo问题记录
    CentOS On VirtualBox
    MySQL GROUP BY用法
  • 原文地址:https://www.cnblogs.com/codderYouzg/p/12419019.html
Copyright © 2011-2022 走看看