84 java网络编程_4 _网络编程

文章目录??基于TCP的网络编程????案例1:TCP编程实现客户端发送数据给服务端????案例2:TCP编程实现客户端上传文件给服务端????案例3:TCP编程实现多个客户端发送数据给服务端????案例4:使用Socket实现注册登录????Tomcat????基于UDP的网络编程????案例1:UDP编程实现发送消息????案例2:UDP聊天实现(单方面循环发送)????案例3:UDP聊天实现(双向)????URL??基于TCP的网络编程Socket编程:Socket (套接字)是网络中的一一个通信节点。分为客户端Socket与服务器ServerSocket。通信要求: IP地址+端口号。(客户端要知道服务器的IP地址+端口号)开发步骤服务器端:创建ServerSocket, 指定端口号调用accept等待客户端接入使用输入流,接收请求数据到服务器(等待)使用输出流,发送响应数据给客户端释放资源客户端:创建Socket, 指定服务器IP +端口号使用输出流,发送请求数据给服务器使用输入流,接收响应数据到客户端(等待)释放资源案例1:TCP编程实现客户端发送数据给服务端

(先运行服务器,再运行客户端)

package com.wlw.computer_network;import java.io.BufferedReader;import java.io.InputStream;import java.io.InputStreamReader;import java.net.ServerSocket;import java.net.Socket;/** * 基于TCP的服务器端开发 * (1)创建ServerSocket, 指定端口号 * (2)调用accept等待客户端接入,接收客户端请求 * (3)使用输入流,(读取客户端发送的数据)接收请求数据到服务器(等待) * (4)使用输出流,发送响应数据给客户端 * (5)释放资源 */public class TcpServer { public static void main(String[] args) throws Exception{ //(1)创建ServerSocket, 指定端口号 ServerSocket serverSocket = new ServerSocket(8899);//ServerSocket就是一个监听作用(负责建立三次握手) //(2)调用accept等待客户端接入,接收客户端请求(阻塞方法,如果没有客户端请求则阻塞) System.out.println(“服务器已启动:”); Socket socket = serverSocket.accept();//Socket来执行操作(进行通信) //(3)使用输入流,(读取客户端发送的数据) InputStream inputStream = socket.getInputStream(); BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream,”utf-8″)); String data = bufferedReader.readLine(); System.out.println(“客户发送:”+data); //(4)使用输出流,发送响应数据给客户端[案例1可选] //(5)释放资源 bufferedReader.close(); socket.close(); serverSocket.close(); }}package com.wlw.computer_network;import java.io.*;import java.net.Socket;/** * 基于TCP的客户端开发 * (1)创建Socket, 指定服务器IP +端口号 * (2)使用输出流,发送请求数据给服务器 * (3)使用输入流,接收响应数据到客户端(等待) * (4)释放资源 */public class TcpClient { public static void main(String[] args) throws Exception{ //(1)创建Socket, 指定服务器IP +端口号 Socket socket = new Socket(“192.168.1.31″, 8899);//创建成功,就和对应的服务器连接成功 //(2)使用输出流,发送请求数据给服务器 OutputStream outputStream = socket.getOutputStream(); BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream,”utf-8”)); bufferedWriter.write(“好久不见”); //(3)使用输入流,接收响应数据到客户端(等待)[案例1可选] //(4)释放资源 bufferedWriter.close(); socket.close(); }}

案例1分析:

?

案例2:TCP编程实现客户端上传文件给服务端package com.wlw.computer_network.case02;import java.io.FileOutputStream;import java.io.InputStream;import java.net.ServerSocket;import java.net.Socket;//服务器public class TcpFileServer { public static void main(String[] args) throws Exception{ //1.创建ServerSocket ServerSocket serverSocket = new ServerSocket(8889); //2.accept 等待客户端接入 System.out.println(“服务器已启动….”); Socket socket = serverSocket.accept(); //3.获取输入流 接收数据 并保存(边读边写) InputStream inputStream = socket.getInputStream(); FileOutputStream fos = new FileOutputStream(“D:\\Program Files\\IDEAworkspace\\file\\Tcp001.jpg”); byte[] date = new byte[1024*4]; int count = 0; while ((count = inputStream.read(date)) != -1){ fos.write(date,0,count); } /* int count = 0; while ((count = inputStream.read()) != -1){ fos.write(count); } */ //关闭 fos.close(); inputStream.close(); socket.close(); serverSocket.close(); System.out.println(“接收完毕”); }}package com.wlw.computer_network.case02;import java.io.FileInputStream;import java.io.OutputStream;import java.net.Socket;//客户端public class TcpFileClient { public static void main(String[] args) throws Exception{ //1.创建Socket, 指定服务器IP +端口号 Socket socket = new Socket(“192.168.1.31”, 8889); //2.获取输出流 边写边上传 OutputStream outputStream = socket.getOutputStream(); FileInputStream fis = new FileInputStream(“D:\\Program Files\\IDEAworkspace\\file\\001.jpg”); byte[] data = new byte[1024*4]; int count = 0; while ((count = fis.read(data)) != -1){ outputStream.write(data,0,count); } /* int count = 0; while ((count = fis.read()) != -1){ outputStream.write(count); } */ //关闭 fis.close(); outputStream.close(); socket.close(); System.out.println(“发送完毕”); }}案例3:TCP编程实现多个客户端发送数据给服务端package com.wlw.computer_network.case03;import java.io.BufferedReader;import java.io.InputStream;import java.io.InputStreamReader;import java.net.ServerSocket;import java.net.Socket;//TCP编程实现多个客户端发送数据给服务端public class TcpServer { public static void main(String[] args) throws Exception{ //1.创建ServerSocket, 指定端口号 ServerSocket serverSocket = new ServerSocket(8887); //2.调用accept等待客户端接入,接收客户端请求 System.out.println(“服务器启动了……..”); while (true){ Socket socket = serverSocket.accept(); System.out.println(socket.getInetAddress()+”进来了…..”); //创建线程对象,负责接收数据 SocketThread socketThread = new SocketThread(socket); socketThread.start(); } }}package com.wlw.computer_network.case03;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.net.Socket;public class SocketThread extends Thread { private Socket socket; public SocketThread(Socket socket) { this.socket = socket; } @Override public void run() { if(socket != null){ BufferedReader bufferedReader = null; try { //获取输入流 InputStream inputStream = socket.getInputStream(); bufferedReader = new BufferedReader(new InputStreamReader(inputStream,”utf-8″)); while (true){ String data = bufferedReader.readLine(); if(data == null){//客户端关闭了 break; } System.out.println(socket.getInetAddress()+”说:”+data); if(data.equals(“886”) || data.equals(“byebye”)){ break; } } } catch (IOException e) { e.printStackTrace(); }finally { try { bufferedReader.close(); socket.close(); System.out.println(socket.getInetAddress()+”退出了……..”); } catch (IOException e) { e.printStackTrace(); } } } }}package com.wlw.computer_network.case03;import java.io.BufferedWriter;import java.io.OutputStream;import java.io.OutputStreamWriter;import java.net.Socket;import java.util.Scanner;//TCP编程实现多个客户端发送数据给服务端//客户端时持续一直向服务端发送数据public class TcpClient { public static void main(String[] args) throws Exception{ //1.创建Socket, 指定服务器IP +端口号 Socket socket = new Socket(“192.168.1.31″, 8887); //2.获取输出流 OutputStream outputStream = socket.getOutputStream(); BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream,”utf-8”)); //3.控制台输入数据 Scanner input = new Scanner(System.in); System.out.println(“请输入你的消息:”); while (true){ String data = input.nextLine(); bufferedWriter.write(data); bufferedWriter.newLine(); bufferedWriter.flush(); if(data.equals(“886”) || data.equals(“byebye”)){ break; } } //3.关闭 bufferedWriter.close(); outputStream.close(); socket.close(); }}案例4:使用Socket实现注册登录使用Scoket编程实现服务器端注册:注册信息保存在properties文件中。封装格式:id={id:”1001”,name:“tom”,pwd:”123”,age:20}注册成功后返回字符串“ 注册成功 ”。使用Scoket编程实现服务器端登录:获取properties文件中的用户信息, 进行用户id与密码的校验。校验成功后返回字符串“登录成功”。package com.wlw.computer_network.case04_1;//启动程序public class UserServer { public static void main(String[] args) { new RedistThread().start(); new LoginThread().start(); }}package com.wlw.computer_network.case04_1;import java.io.*;import java.net.ServerSocket;import java.net.Socket;import java.util.Properties;public class RedistThread extends Thread{ @Override public void run() { ServerSocket serverSocket = null; Socket socket = null; BufferedReader bufferedReader = null; BufferedWriter bufferedWriter = null; try { //1.创建ServerSocket serverSocket = new ServerSocket(8704); //2.调用accept等待客户端接入,接收客户端请求 System.out.println(“注册服务器已启动…..”); socket = serverSocket.accept(); //3.获取输入 输出流 InputStream inputStream = socket.getInputStream(); bufferedReader =new BufferedReader(new InputStreamReader(inputStream,”utf-8″)); OutputStream outputStream = socket.getOutputStream(); bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream,”utf-8″)); //4.用流获取客户端注册方法传过来的信息 {id:1001,name:tom,pwd:123,age:20},数据是这样的形式 String json = bufferedReader.readLine();//得到用户传过来的格式化信息 String[] splitdata = json.substring(1, json.length() – 1).split(“,”); String id = splitdata[0].split(“:”)[1];//得到用户传过来的id值 //5.对比id值 判断是注册,还是用户已经注册 //5.1获取(加载) 已经保存的用户信息 Properties properties = Tools.loadProperties(); if( properties.containsKey(id)){ //id 已经在属性文件中 //回复 bufferedWriter.write(“用户已存在………..”); }else { //5.2保存信息 Tools.storeProperties(json); //回复 bufferedWriter.write(“注册成功”); } bufferedWriter.newLine(); bufferedWriter.flush(); } catch (IOException e) { e.printStackTrace(); }finally { //关闭释放 if(bufferedWriter != null){ try { bufferedWriter.close(); } catch (IOException e) { e.printStackTrace(); } } if(bufferedReader != null){ try { bufferedReader.close(); } catch (IOException e) { e.printStackTrace(); } } if(socket != null){ try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } if(serverSocket != null){ try { serverSocket.close(); } catch (IOException e) { e.printStackTrace(); } } } }}package com.wlw.computer_network.case04_1;import java.io.*;import java.util.Properties;public class Tools { //加载 属性文件 public static Properties loadProperties(){ Properties properties = new Properties(); File file = new File(“usres2.peoperties”); FileInputStream fis = null; if(file.exists()){ try { fis = new FileInputStream(file); properties.load(fis); } catch (Exception e) { e.printStackTrace(); }finally { if(fis != null){ try { fis.close(); } catch (IOException e) { e.printStackTrace(); } } } } return properties; } //保存 属性文件 public static void storeProperties(String json){ String[] splitdata = json.substring(1, json.length() – 1).split(“,”); String id = splitdata[0].split(“:”)[1];//得到用户传过来的id值 Properties properties = new Properties(); FileOutputStream fos = null; try { properties.setProperty(id,json);//要保存的信息,以id值为键 fos = new FileOutputStream(“usres2.peoperties”,true);//信息追加,而不是覆盖 properties.store(fos,””); } catch (Exception e) { e.printStackTrace(); }finally { if(fos != null){ try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } } }}package com.wlw.computer_network.case04_1;import java.io.*;import java.net.ServerSocket;import java.net.Socket;import java.util.Properties;public class LoginThread extends Thread { @Override public void run() { ServerSocket serverSocket = null; Socket socket = null; BufferedReader bufferedReader = null; BufferedWriter bufferedWriter = null; try { //1.创建ServerSocket serverSocket = new ServerSocket(8705); //2.调用accept等待客户端接入,接收客户端请求 System.out.println(“登录服务器已启动…..”); socket = serverSocket.accept(); //3.获取输入 输出流 InputStream inputStream = socket.getInputStream(); bufferedReader =new BufferedReader(new InputStreamReader(inputStream,”utf-8″)); OutputStream outputStream = socket.getOutputStream(); bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream,”utf-8″)); //4.用流获取客户端登录方法传过来的信息 {id:1001,pwd:123},数据是这样的形式 String json = bufferedReader.readLine();//得到用户传过来的格式化信息 String[] splitdata = json.substring(1, json.length() – 1).split(“,”); String id = splitdata[0].split(“:”)[1];//得到用户传过来的id值 //5.对比id值 和密码 判断是否正确 //5.1获取(加载) 已经保存的用户信息 Properties properties = Tools.loadProperties(); if( properties.containsKey(id)){ //id 正确 //判断密码 是否正确 String password = splitdata[1].split(“:”)[1];//得到用户传过来的密码 String value = properties.getProperty(id); String[] splitvalue = value.substring(1, value.length()).split(“,”); String password2 = splitvalue[2].split(“:”)[1];//从users2.properties文件中获取的密码 if(password.equals(password2)){ bufferedWriter.write(“登录成功”); }else { bufferedWriter.write(“密码错误”); } }else { //回复 bufferedWriter.write(“用户编号错误”); } bufferedWriter.newLine(); bufferedWriter.flush(); } catch (IOException e) { e.printStackTrace(); }finally { //关闭释放 if(bufferedWriter != null){ try { bufferedWriter.close(); } catch (IOException e) { e.printStackTrace(); } } if(bufferedReader != null){ try { bufferedReader.close(); } catch (IOException e) { e.printStackTrace(); } } if(socket != null){ try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } if(serverSocket != null){ try { serverSocket.close(); } catch (IOException e) { e.printStackTrace(); } } } }}package com.wlw.computer_network.case04_1;import java.io.*;import java.net.Socket;import java.util.Scanner;//客户端 登陆注册public class UserClient { public static void main(String[] args) throws Exception{ Scanner input = new Scanner(System.in); System.out.println(“————–请选择1注册 2登录————————“); int choice = input.nextInt(); switch (choice){ case 1: regist(); break; case 2: login(); break; default: break; } } public static void regist() throws Exception{ //1.创建Socket, 指定服务器IP +端口号 Socket socket = new Socket(“192.168.1.31″, 8704); //2.获取输入 输出流 OutputStream outputStream = socket.getOutputStream(); BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream,”utf-8″)); InputStream inputStream = socket.getInputStream(); BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream,”utf-8”)); //3.发送数据 String jsonData = getRegistdata(); bufferedWriter.write(jsonData); bufferedWriter.newLine(); bufferedWriter.flush(); //4.接收服务器的回复 String repaly = bufferedReader.readLine(); System.out.println(“服务器回复:”+repaly); //5.关闭释放 bufferedReader.close(); bufferedWriter.close(); socket.close(); } public static String getRegistdata(){ Scanner inpput = new Scanner(System.in); System.out.println(“请输入用户编号:”); int id = inpput.nextInt(); System.out.println(“请输入用户名称:”); String name = inpput.next(); System.out.println(“请输入用户密码:”); int password = inpput.nextInt(); System.out.println(“请输入用户年龄:”); int age = inpput.nextInt(); String json = “{id:”+id+”,name:”+name+”,pwd:”+password+”,age:”+age+”}”; return json; } public static void login() throws Exception{ //1.创建Socket, 指定服务器IP +端口号 Socket socket = new Socket(“192.168.1.31″, 8705); //2.获取输入 输出流 OutputStream outputStream = socket.getOutputStream(); BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream,”utf-8″)); InputStream inputStream = socket.getInputStream(); BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream,”utf-8”)); //3.发送数据 String jsonData = getLogindata(); bufferedWriter.write(jsonData); bufferedWriter.newLine(); bufferedWriter.flush(); //4.接收服务器的回复 String repaly = bufferedReader.readLine(); System.out.println(“服务器回复:”+repaly); //5.关闭释放 bufferedReader.close(); bufferedWriter.close(); socket.close(); } public static String getLogindata(){ Scanner inpput = new Scanner(System.in); System.out.println(“请输入用户编号:”); int id = inpput.nextInt(); System.out.println(“请输入用户密码:”); int password = inpput.nextInt(); String json = “{id:”+id+”,pwd:”+password+”}”; return json; }}Tomcat

服务端

自定义STomcat服务器

客户端

自定义C浏览器B基于UDP的网络编程

TCP像打电话,需要连接

UDP像发短信,不用连接,需要知道对方的地址!

Udp没有真正的客户端和服务器的概念,为了区分,我们可以加上。(发送端和接收端)

案例1:UDP编程实现发送消息package com.wlw.computer_network.case05;import java.net.DatagramPacket;import java.net.DatagramSocket;import java.net.InetAddress;//UDPpublic class UdpClientDemo01 { public static void main(String[] args) throws Exception{ //1.创建一个DatagramSocket(数据报套接字) DatagramSocket datagramSocket = new DatagramSocket(); //建个包 DatagramPacket(数据报包),并指定发给谁 String msg = “你好啊,服务器”; InetAddress localhost = InetAddress.getByName(“127.0.0.1”); int port = 9989; //数据,数据的起始,数据的长度,要发给谁的地址与端口号 DatagramPacket packet = new DatagramPacket(msg.getBytes(), 0, msg.getBytes().length, localhost, port); //2.发送包 datagramSocket.send(packet); //3.关闭 datagramSocket.close(); }}package com.wlw.computer_network.case05;import java.net.DatagramPacket;import java.net.DatagramSocket;//udppublic class UdpServerDemo01 { public static void main(String[] args) throws Exception{ //1.创建一个DatagramSocket(数据报套接字) 开放端口 DatagramSocket socket = new DatagramSocket(9989); //建个包来接收 byte[] data = new byte[1024]; DatagramPacket packet = new DatagramPacket(data,0,data.length); //2.接收数据报包 socket.receive(packet);//阻塞接收 System.out.println(“发送方的地址:”+packet.getAddress().getHostAddress()); System.out.println(“发送方的消息:”+new String(packet.getData(),0,packet.getData().length)); //3.关闭 socket.close(); }}/*发送方的地址127.0.0.1发送方的消息:你好啊,服务器 */案例2:UDP聊天实现(单方面循环发送)package com.wlw.computer_network.case05;import java.io.BufferedInputStream;import java.io.BufferedReader;import java.io.InputStreamReader;import java.net.DatagramPacket;import java.net.DatagramSocket;import java.net.InetSocketAddress;//发送方public class UdpSenderDemo01 { public static void main(String[] args) throws Exception{ //1.DatagramSocket DatagramSocket socket = new DatagramSocket(); BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); while (true){//一直发送数据 //数据 String readData = reader.readLine(); byte[] data = readData.getBytes(); //包 DatagramPacket packet = new DatagramPacket(data,0,data.length,new InetSocketAddress(“127.0.0.1”,6666)); socket.send(packet); //2.发送 if(readData.equals(“bye”) || readData.equals(“拜拜”)){ break; } } //3.关闭 socket.close(); }}package com.wlw.computer_network.case05;import java.io.BufferedReader;import java.io.InputStreamReader;import java.net.DatagramPacket;import java.net.DatagramSocket;import java.net.InetSocketAddress;import java.net.SocketException;//接收方public class UdpReceiveDemo01 { public static void main(String[] args) throws Exception { //1.DatagramSocket,开放端口 DatagramSocket socket = new DatagramSocket(6666); while (true){//一直接收 byte[] data = new byte[1024]; //包 DatagramPacket packet = new DatagramPacket(data,0,data.length); socket.receive(packet);//2.阻塞接收 /接收 String datas = new String(packet.getData(), 0, packet.getData().length); System.out.println(“发送方说:”+datas); if(datas.equals(“bye”) || datas.equals(“拜拜”)){ break; } } //3.关闭 socket.close(); }}案例3:UDP聊天实现(双向)package com.wlw.computer_network.case06;public class TalkTeacher { public static void main(String[] args) { new Thread(new TalkSend(6666,”localhost”,8888)).start(); new Thread(new TalkReceive(9999,”学生”)).start(); }}package com.wlw.computer_network.case06;public class TalkStudent { public static void main(String[] args) { new Thread(new TalkSend(5555,”localhost”,9999)).start(); new Thread(new TalkReceive(8888,”教师”)).start(); }}package com.wlw.computer_network.case06;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.net.DatagramPacket;import java.net.DatagramSocket;import java.net.InetSocketAddress;import java.net.SocketException;//发送public class TalkSend extends Thread{ DatagramSocket socket = null; BufferedReader reader = null; private int formPort; private String toIp; private int toPort; public TalkSend(int formPort, String toIp, int toPort) { this.formPort = formPort; this.toIp = toIp; this.toPort = toPort; try { //1.DatagramSocket socket = new DatagramSocket(formPort); reader = new BufferedReader(new InputStreamReader(System.in)); System.out.println(“你可以发送消息了……….”); } catch (SocketException e) { e.printStackTrace(); } } @Override public void run() { while (true){//一直发送数据 //数据 String readData = null; try { readData = reader.readLine(); byte[] data = readData.getBytes(); //包 DatagramPacket packet = new DatagramPacket(data,0,data.length,new InetSocketAddress(this.toIp,this.toPort)); socket.send(packet); //2.发送 if(readData.equals(“bye”) || readData.equals(“拜拜”)){ break; } } catch (IOException e) { e.printStackTrace(); } } //3.关闭 socket.close(); }}package com.wlw.computer_network.case06;import java.io.IOException;import java.net.DatagramPacket;import java.net.DatagramSocket;import java.net.SocketException;//接收public class TalkReceive extends Thread{ DatagramSocket socket = null; private int port; private String msgForm; public TalkReceive(int port, String msgForm) { this.port = port; this.msgForm = msgForm; try { //1.DatagramSocket,开放端口 socket = new DatagramSocket(port); } catch (SocketException e) { e.printStackTrace(); } } @Override public void run() { while (true){//一直接收 try { //准备接收数据 byte[] data = new byte[1024]; DatagramPacket packet = new DatagramPacket(data,0,data.length); //包 socket.receive(packet);//2.阻塞接收 /接收 String datas = new String(packet.getData(), 0, packet.getData().length); System.out.println(msgForm+”:”+datas); if(datas.equals(“bye”) || datas.equals(“拜拜”)){ break; } } catch (IOException e) { e.printStackTrace(); } } //3.关闭 socket.close(); }}URL

??https://www.baidu.com??

统一资源定位符:定位资源的,定位互联网上的某一个资源

DNS 域名解析: www.baidu.com xxx.x…x…x…

协议://ip地址:端口/项目名/资源package com.wlw.computer_network.case07;import java.net.MalformedURLException;import java.net.URL;public class URLDemo01 { public static void main(String[] args) throws MalformedURLException { URL url = new URL(“http://localhost:8080/helloworld/index.jsp?username=dahai&password=123”); System.out.println(url.getProtocol()); //协议 System.out.println(url.getHost());//主机IP System.out.println(url.getPort());//端口 System.out.println(url.getPath());//文件 System.out.println(url.getFile());//全路径 System.out.println(url.getQuery());//参数 }}package com.wlw.computer_network.case07;import java.io.FileOutputStream;import java.io.InputStream;import java.net.HttpURLConnection;import java.net.MalformedURLException;import java.net.URL;import java.net.URLConnection;//可以下载网上的一些文件// http://localhost:8080/wlw/SecurityFile.txtpublic class URLDown { public static void main(String[] args) throws Exception { //1.下载地址 URL url = new URL(“http://localhost:8080/wlw/SecurityFile.txt”); //2.连接到这个资源 HttpURLConnection connection = (HttpURLConnection)url.openConnection(); //3.获得流 InputStream is = connection.getInputStream(); FileOutputStream fos = new FileOutputStream(“D:\\Downloads\\SecurityFile.txt”); byte[] data = new byte[1024]; int len; while ((len = is.read(data)) != -1){ fos.write(data,0,len); } //关闭释放 fos.close(); is.close(); connection.disconnect(); }}

期待遇上一位撑着油纸伞,结着忧愁丁香一样的姑娘;或者在春暖花开时,

84 java网络编程_4 _网络编程

相关文章:

你感兴趣的文章:

标签云: