Java学习日志Day26_Properties属性集合类_网络Socket编程

一、Properties属性集合类

  1. Properties 继承自Hashtable<K,V>---->实现Map<K,V>接口
    表示了一个持久的属性集
    Properties 可保存在流中或从流中加载。属性列表中每个键及其对应值都是一个字符串。
    构造方法
    public Properties()
举例:
public class PropertiesDemo {

    public static void main(String[] args) {

        //Properties没有泛型,属于Map的一个子实现类
        //使用Map接口的功能操作

        //创建一个属性列表
        Properties properties = new Properties() ;

        //put
        properties.put("张三",30) ;
        properties.put("李四",40) ;
        properties.put("王五",50) ;
        properties.put("赵六",25) ;

        //遍历:Map集合遍历方式: 推荐:keySet()
        Set<Object> keySet = properties.keySet();
        for(Object obj :keySet){
            //通过键获取值
            Object value = properties.get(obj);
            System.out.println(obj+"---"+value);
        }
    }
}
  1. 关于属性集合类的特有功能:
    添加方法
    public Object setProperty(String key,String value)
    遍历:
    public Set stringPropertyNames()
    通过键获取值
    public String getProperty(String key)
举例:
public class PropertiesDemo2 {

    public static void main(String[] args) {
        //创建一个属性集合类
        Properties prop = new Properties() ;

        //添加
        prop.setProperty("1","文章") ;
        prop.setProperty("2","高圆圆") ;
        prop.setProperty("3","马伊琍") ;
        prop.setProperty("4","赵又廷") ;
        prop.setProperty("4","王宝强") ;

        //遍历
        Set<String> keySet = prop.stringPropertyNames();
        for(String key:keySet){
            //通过键获取值
            String value = prop.getProperty(key);
            System.out.println(key+"---"+value);
        }
    }
}
  1. 关于属性集合类的应用;
    1)因为键和值都是String,所以可能将键和值的保存在文本文件或者配置文件中 :加载过程
    public void load(Reader reader)throws IOException
    public void load(InputStream in)throws IOException

    2)将属性集合类中的内容写出到某个文件中:保存过程
    public void store(OutputStream out,String comments) throws IOException
    参数1:当前字节输出流
    参数2:给当前属性列表中写入完毕之后,注释的内容
    public void store(Writer writer,String comments) throws IOException
    将当前项目下的name.txt内容加载到属性集合类中

举例:
public class PropertiesDemo3 {
    public static void main(String[] args) throws IOException {

      //  myLoad() ;

     //   mySotre() ;
    }

    //保存:将当前属性集合类中的内容,输出在某个文件中
    private static void mySotre() throws IOException {
        //创建一个属性列表
        Properties prop = new Properties() ;
        prop.setProperty("马伊琍","35") ;
        prop.setProperty("文章","26") ;
        prop.setProperty("姚笛","22") ;
        prop.setProperty("王宝强","35") ;
        prop.setProperty("马蓉","30") ;

        //保存
        prop.store(new FileWriter("userList.txt"),"name's list");

    }

    //加载:将name.txt内容加载到属性集合类中
    private static void myLoad() throws IOException {
        //创建一个属性集合类
        Properties prop = new Properties() ;
        System.out.println(prop);

        //加载
        //字符流
        Reader r = new FileReader("name.txt") ;
        prop.load(r);

        //遍历
        Set<String> keySet = prop.stringPropertyNames();
        for (String key: keySet) {
            String value = prop.getProperty(key) ;
            System.out.println(key+"---"+value);
        }

        //System.out.println(prop);
    }
}
  1. 如果我们的配置文件后缀名xx.properties
    操作步骤:
    src目录下---->类路径
    将properties配置文件放置在src目录下
举例:
public class PropertiesDemo4 {

    public static void main(String[] args) throws IOException {

        //读取user.properties配置文件: src目录下
        //1)需要获取当前类的字节码文件对象( PropertiesDemo4类中要使用配置文件)
   /*     Class clazz = PropertiesDemo4.class ;
        //2)获取当前类的类加载器
        //Class类的方法:getClassLoader()--->ClassLoader
        ClassLoader classLoader = clazz.getClassLoader();

        //public InputStream getResourceAsStream(String name) :传入当前配置文件-->获取当前配置资源的输入流对象(推荐)
        //public URL getResource(String name):传入配置文件名称-->获取当前配置文件的url地址
       //通过类加载将配置文件的内容读取到了流中
        InputStream inputStream = classLoader.getResourceAsStream("user.properties");
*/

        //一步走
        InputStream inputStream = PropertiesDemo4.class.getClassLoader().getResourceAsStream("user.properties");
        //创建属性集合类中
        Properties prop = new Properties() ;
        prop.load(inputStream);

        //System.out.println(prop);
        Set<String> keySet = prop.stringPropertyNames();
        for(String key:keySet){

            System.out.println(key+"---"+prop.getProperty(key));
        }

    }
}

二、网络编程Socket

  1. UDP协议发送端的实现步骤: (不需要建立连接通道,以"数据报包"的方式发送数据)
    DatagramSocket表示用来发送和接收"数据报包"的套接字
    1)创建发送端的Socket: DatagramSocket
    public DatagramSocket() throws SocketException{}
    2) 创建 "数据报包"对象
    public DatagramPacket(byte[] buf,int length,InetAddress address,int port)
    3)发送数据报包
    public void send(DatagramPacket p) throws IOException
    4)释放资源
    close()关闭socket对象
举例:
public class SendDemo {
    public static void main(String[] args) throws IOException {
        //创建发送端的Socket:  DatagramSocket
        DatagramSocket ds = new DatagramSocket() ;

        //创建 "数据报包"对象
//         public DatagramPacket(byte[] buf,int length,InetAddress address,int port)
        //参数1:包的数据--字节数组
        //参数2:包的长度
        //参数3:ip地址
        //参数4:端口号
        String messageStr = "hello,UDP,我来了" ;
        byte[] bytes = messageStr.getBytes();
        int length = bytes.length ;
        InetAddress inetAddress = InetAddress.getByName("10" +
                ".12.152.129");
        int port = 10086 ;
        DatagramPacket dp = new DatagramPacket(bytes, length, inetAddress, port);

        //3)发送数据
        ds.send(dp);
        System.out.println("当前数据已经发送...");

        //4)释放资源
        ds.close();
    }
}
  1. UDP协议接收端实现
    1)创建接收端的Socket
    public DatagramSocket(int port) throws SocketException:绑定端口号
    2)数据一个数据报包对象:DatagramPacket
    接收容器
    public DatagramPacket(byte[] buf, int length) :获取的是缓冲区的数据(不是真实数据)
    一般情况:byte[] bytes = new byte[1024] ; 自定义字节缓冲区
    3)接收
    public void receive(DatagramPacket p):阻塞式方法:在接收数据之前,一直处于阻塞状态,直到
    当前接收端监听客户端口号了
    4) 获取缓冲区的传递的真实数据
    public byte[] getData():获取真实的字节数组
    public int getLength():获取实际长度
    将获取的字节数据---->String(byte[] bytes,int offset,int length)
    获取哪个发送端传递的数据:ip 文本形式:
    public InetAddress getAddress()
    IntegerAddss—>public String getHostAddress()
    5)使用完毕,关闭接收端
    接收端不能运行多次,否则出现异常了,端口号被占用!
举例:
public class ReceiveDemo {
    public static void main(String[] args) throws IOException {

        System.out.println("接收端等待发送数据...");

        //创建接收端的Socket
        DatagramSocket ds = new DatagramSocket(10086) ;

        // 接收容器:数据报包
        //定义一个字节缓冲区
        byte[] bytes = new byte[1024] ;
        int length = bytes.length ;
        DatagramPacket dp = new DatagramPacket(bytes,length) ;

        //接收
        ds.receive(dp);
        System.out.println("已经获取发送数据准备解析...");

        //解析真实数据
        /*
        * public byte[] getData():获取真实的字节数组
         *      public int getLength():获取实际长度*/
        byte[] bytes2 = dp.getData();
        int len = dp.getLength();
        //获取ip地址
        String ip = dp.getAddress().getHostAddress();
        String receiveMsgStr = new String(bytes2,0,len) ;

        System.out.println("data from " + ip +"and content is:  "+receiveMsgStr);

        //关闭资源
        ds.close();
    }
}
  1. 想通过程序的方式:获取本地计算机的这个ip字符串形式以及主机名称?

java.net.InetAddress:互联协议的ip地址!

一个具体类中,没有字段,没有构造方法,
    那么这个类只有成员方法,成员方法里面存在静态功能,返回值是它本身!
            单例模式:
     Runtime
            private static Runtime currentRuntime = new Runtime() ;
            private Runtime(){}
            public static Runtime getRuntime(){
               return currentRuntime
			}

public static InetAddress getByName(String host):给定主机名称,可以获取互联网ip地址对象!
参数:可以传递主机名称/ip地址名称

    public String getHostAddress():获取ip地址字符串形式
    public String getHostName():获取主机名称
举例:
public class InetAddressDemo {
    public static void main(String[] args) throws UnknownHostException {
//        InetAddress inetAddress = InetAddress.getByName("LAPTOP-BHL76J0S");
        InetAddress inetAddress = InetAddress.getByName("10.12.152.131");

        //获取ip地址字符串文本
        String ip = inetAddress.getHostAddress();
        System.out.println(ip);//10.12.152.129

        //获取主机名称
        String hostName = inetAddress.getHostName();
        System.out.println(hostName);//LAPTOP-BHL76J0S

        //LAPTOP-4IJ0OFL4
    }
}

/*  udp发送端不断的键盘录入数据,当前录入是 "over/886",结束,接收端不断的接收数据!
 *          键盘录入数据采用的是:BufferedReader的readLine()功能来操作
 */
public class SendDemo {
    public static void main(String[] args) {
        //创建一个字符缓冲输入流

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in)) ;
        //创建一个送端的Socket对象
        DatagramSocket ds = null ;

        try {
             ds = new DatagramSocket() ;
            String line = null ;
            while((line=br.readLine())!=null){
                //自定义结束条件
                if("886".equals(line)){
                    break ;
                }
                //创建数据报包
                DatagramPacket dp = new DatagramPacket(
                        line.getBytes(),
                        line.getBytes().length,
                        InetAddress.getByName("10.12.152.129"),
                        10010);
                ds.send(dp);
            }
        } catch (SocketException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(ds!=null){
                ds.close();
            }
        }
    }
}

/* Udp接收端不断的接收数据,接收端一般不关闭(模拟真实场景)
 */
public class ReceiveDemo {
    public static void main(String[] args)  throws  Exception{
        try {
            System.out.println("等待接收");
            DatagramSocket ds =new DatagramSocket(10010) ;


        while(true){
            //创建接收端的Socket对象
                //创建数据报包:接收容器
                DatagramPacket dp = new DatagramPacket(new byte[1024],new byte[1024].length) ;
                //接收
                ds.receive(dp);

                //准备解析真实数据
                String str = new String(dp.getData(),0,dp.getLength()) ;
                String ip = dp.getAddress().getHostAddress() ;
                System.out.println("data from: "+ip+" and content is: "+str );

//                ds.close(); //接收端不需要关闭
            }
        } catch (SocketException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
  1. 如何使用udp方式在一个窗口下进行聊天
    需要两条线程:发送端发消息的线程
    接收端接收消息的线程
    创建线程的方式:(除过线程池)
    1)继承自Thread类
    2)实现Runnable接口 —> 能够多个线程占用的 内存空间(共享共用)
    代理----静态代理模式
举例:
发送端的资源类
public class SendThread implements  Runnable {

    private DatagramSocket ds ;
    public SendThread(DatagramSocket ds){
        this.ds = ds ;
    }


    @Override
    public void run() {
        try {
            //不断键盘录入数据
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in)) ;
            String line = null ;
            while((line=br.readLine())!=null){
                if("over".equals(line)){
                    break ;
                }

                //创建数据报包
                DatagramPacket dp = new DatagramPacket(line.getBytes(),
                        line.getBytes().length,
                        InetAddress.getByName("10.12.152.129"),
                        12306);

                //发送数据
                ds.send(dp) ;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            if(ds!=null){
                ds.close();
            }
        }

    }
}

/* 接收端的资源类对象
 */
public class ReceiveThread implements Runnable {

    private DatagramSocket ds ;
    public ReceiveThread(DatagramSocket ds){
        this.ds = ds ;
    }

    @Override
    public void run() {

        try {
            while(true){
                //创建接收端的Socket对象
                //创建数据报包:接收容器
                DatagramPacket dp = new DatagramPacket(new byte[1024],new byte[1024].length) ;
                //接收
                ds.receive(dp);

                //准备解析真实数据
                String str = new String(dp.getData(),0,dp.getLength()) ;
                String ip = dp.getAddress().getHostAddress() ;
                System.out.println("data from: "+ip+" and content is: "+str );

            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        //接收不需要关闭
    }
}

public class ChatRoom {
    public static void main(String[] args) throws Exception{

        //创建两端的Socket对象
        //发送端:
        DatagramSocket ds = new DatagramSocket() ;
        //接收端
        DatagramSocket ds2 = new DatagramSocket(12306) ;

        //创建资源类对象
        //发送端的资源类以及接收端端的子类
        SendThread st  = new SendThread(ds) ;
        ReceiveThread rt = new ReceiveThread(ds2) ;

        //创建线程对象
        Thread t1 = new Thread(st) ;
        Thread t2 = new Thread(rt) ;
        t1.start();
        t2.start();
    }
}
  1. TCP/IP协议:客户端发送的过程
    1)创建客户端的Socket
    public Socket(String host,int port) throws UnknownHostException,IOException
    2)public OutputStream getOutputStream()throws IOException
    获取当前客户端对象所在的通道内的输出流对象
    3)使用当前通道内的字节输出流 写数据过去
    4)释放资源
举例:
/*服务器端
 *  1)创建服务器端的Socket  :此类实现服务器套接字
 *      public ServerSocket(int port)
 *              throws IOException
 *  2)监听客户端连接
 *      public Socket accept()
 *               throws IOException
 * 3)     通过监听到的客户端对象 获取通道的输入流
 *      public InputStream getInputStream()
 * 4)关闭资源
 *      服务器端关闭
 */
public class ServerSocketDemo {
    public static void main(String[] args) throws IOException {

        //创建服务器端的Socket
        ServerSocket ss = new ServerSocket(6666) ; //一旦能成功,就立即建立通道
        System.out.println("服务器正在等待连接...");

        //2)监听并获取客户端的socket对象
        Socket socket = ss.accept(); //阻塞式方法 如果没有监听到,一直等
        //3)获取通道内的输入流
        InputStream inputStream = socket.getInputStream();
        //一次读取一个字节数组
        byte[] bytes = new byte[1024] ;
        int len = inputStream.read(bytes);
        String str = new String(bytes,0,len) ;

        //通过监听到客户端的socket对象获取ip地址
        String ip = socket.getInetAddress().getHostAddress();
        System.out.println("data from :" +ip +" content is :"+str);
        System.out.println("服务器端接收完毕...");

        //释放资源
        ss.close();

    }
}

public class ClientDemo {
    public static void main(String[] args) throws IOException {

        //1)创建客户端的Socket
        Socket socket = new Socket("10.12.152.129",6666) ;

        //2)获取当前客户端对象所在的通道内的输出流对象
        OutputStream outputStream = socket.getOutputStream();

        //3)写数据
        outputStream.write("hello,TCP,我来了".getBytes());

        //4)释放资源
        socket.close();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

igfff

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值