【自学java笔记#第三十七天#】网络通信基础与Stream流初体验

一、网络通信基础知识点大纲:

 

 

 二、Stream流知识点大纲:

 

 

 三、几道练习题

1、UDP通信协议的练习:

发送端要求:

1、数据来自于键盘录入
2、直到输入的数据是886,发送数据结束

代码如下:

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 InetAddressDemo1 {
    public static void main(String[] args) throws IOException {
        //创建发送端的Socket对象
        DatagramSocket ds=new DatagramSocket();
        
        //自己封装键盘录入数据
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        String line;
        while((line=br.readLine())!=null) {
            //输入的数据是886,发送数据结束
            if("886".equals(line)) {
                break;
            }
            //创建数据,并把数据打包
            byte[] bys=line.getBytes();
            DatagramPacket dp=new DatagramPacket(bys,bys.length,InetAddress.getByName("192.168.1.101"),12345);
            ds.send(dp);
        }
        ds.close();
        
        
    }

}

接收端要求:

因为接收端不知道发送端什么时候停止发送,故采用死循环接收

代码如下:

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;


public class InetAddressDemo {
    public static void main(String[] args) throws IOException {
        //创建接收端Socket对象
        DatagramSocket ds=new DatagramSocket(12345);
        
        while(true) {
        //创建一个数据包,用于接收数据
        byte[] bys=new byte[1024];
        DatagramPacket dp=new DatagramPacket(bys,bys.length);
        
        //调用DatagramSocket对象的方法接收数据
        ds.receive(dp);
        
        //解析数据包,并把数据包放在控制台显示
        System.out.println("数据是:"+new String(dp.getData(),0,dp.getLength()));
        }
        
//        //关闭接收端
//        ds.close();
    }

}

2、TCP协议通信练习:

客户端要求:

数据来自于文本文件,接收服务器反馈

代码如下:

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;


public class InetAddressDemo {
    public static void main(String[] args) throws IOException {
        //创建客户端Socket对象
        Socket sk=new Socket("192.168.1.101",12345);
        
        //数据来自于文本文件
        BufferedReader br=new BufferedReader(new FileReader("D:\\Employee.txt"));
        
        //封装输出流对象
        BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(sk.getOutputStream()));
        
        String line;
        while((line=br.readLine())!=null) {
            bw.write(line);
            bw.newLine();
            bw.flush();
        }
    
        //public void shutdownOutput()
        sk.shutdownOutput();
        
        //接收反馈
        BufferedReader brC=new BufferedReader(new InputStreamReader(sk.getInputStream()));
        String data=brC.readLine();//等待读取数据
        System.out.println("服务器的反馈:"+data);
        
        //释放资源
        sk.close();
        br.close();
    }

}

服务器端要求:

1、接收到的数据写入到文本文件,给出反馈
2、代码用线程进行封装,为每一个客户端开启一个线程

代码如下:

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class InetAddressDemo1 {
    public static void main(String[] args) throws IOException {
        //创建服务器Socket对象
        ServerSocket ss=new ServerSocket(12345);
        
        while(true) {
        //监听客户端的连接,返回一个Socket对象
        Socket s=ss.accept();
        
        //为每一个客户端开启一个线程
        new Thread(new ServerThread(s)).start();
        }
    }

}

实现Runnable接口的类设计如下:

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;

public class ServerThread implements Runnable {

    private Socket s;
    
    public ServerThread(Socket s) {
        this.s=s;
    }
    
    @Override
    public void run() {
        //接收数据写入文本文件
        try {
            BufferedReader bfr=new BufferedReader(new InputStreamReader(s.getInputStream()));
            
//            BufferedWriter bfw=new BufferedWriter(new FileWriter("D:\\troye.txt"));
            //解决名称冲突问题
            int count=0;
            File file=new File("D:\\troye["+count+"].txt");
            while(file.exists()) {
                count++;
                file=new File("D:\\troye["+count+"].txt");
            }
            BufferedWriter bfw=new BufferedWriter(new FileWriter(file));
            
            String line;
            while((line=bfr.readLine())!=null) {
                bfw.write(line);
                bfw.newLine();
                bfw.flush();
            }
            
            //给出反馈
            BufferedWriter bwS=new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
            bwS.write("文件上传成功");
            bwS.newLine();
            bwS.flush();
            
            //释放资源
            s.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

3、Stream流中的收集操作测试程序:

package stream;

/*
 * Stream流中的收集操作
 */
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class StreamTest {
    public static void main(String[] args) {
        // 创建List集合对象
        ArrayList<String> actorList = new ArrayList<String>();
        actorList.add("周润发");
        actorList.add("成龙");
        actorList.add("刘德华");
        actorList.add("吴京");
        actorList.add("周星驰");
        actorList.add("李连杰");

        // 需求1:得到名字为3个字的流
        Stream<String> threeStream = actorList.stream().filter(s -> s.length() == 3);

        // 需求2:把使用Stream流操作完毕的数据收集到List集合中并遍历
//        List<String> coList = threeStream.collect(Collectors.toList());
//        for(String s:coList) {
//            System.out.println(s);
//        }

        // 创建Set集合对象
        HashSet<Integer> set = new HashSet<Integer>();
        set.add(10);
        set.add(20);
        set.add(30);
        set.add(40);
        set.add(50);

        // 需求3:得到年龄大于25的流
        Stream<Integer> ageStream = set.stream().filter(s -> s > 25);

        // 需求4:把使用Stream流操作完毕的数据收集到Set集合中并遍历
//        Set<Integer> colIntegers = ageStream.collect(Collectors.toSet());
//        for(Integer e:colIntegers) {
//            System.out.println(e);
//        }

        // 定义一个字符串数组,每一个字符串数据由姓名数据和年龄数据组合而成
        String[] strArray = { "林青霞,30", "张曼玉,35", "王祖贤,33", "柳岩,25" };

        // 需求5:得到字符串中年龄数据大于28的流
        Stream<String> ageStream2 = Stream.of(strArray).filter(s -> Integer.parseInt(s.split(",")[1]) > 28);

        // 需求6:把使用Stream流操作完毕的数据收集到Map集合中并遍历,字符串中的姓名做键,年龄做值
        Map<String, Integer> map = ageStream2
                .collect(Collectors.toMap(s -> s.split(",")[0], s -> Integer.parseInt(s.split(",")[1])));
        Set<String> keySet = map.keySet();
        for (String key : keySet) {
            Integer value = map.get(key);
            System.out.println("姓名为:" + key + ",年龄为:" + value);
        }
    }
}

 

 

posted @ 2020-04-19 21:44  一只奶鹿  阅读(251)  评论(0)    收藏  举报