JAVA API---Socket,可变参数,枚举

package SocketDemo;

import java.net.InetSocketAddress;

/*
 * 
 * 套接字:
 *        进行网络数据传输的一套API,本质上可以在网络上使用的流
 * 
 * 1.网络基本概念:
 * 		  1.1七层模型:物理层,数据链路层,网络层,传输层(UDP/TCP),会话层,应用层,表示层--HTTP,FTP,POP3,SMTP
 *  
 *        1.2IP地址:在网络中标记主机。  
 *               IPv4:四组数表示一个IP地址        196.120.30.200   每一组数取值范围是0-255  2^8
 *               IPv6:六组数表示一个IP地址
 *               IPv9:
 *               
 *        1.3 端口:计算机与外界交互的媒介。   端口号:0~65535     熟知端口号0-1024  客户端端口号:1025-65535
 *        
 *        1.4域名:各个网站所提供的便于记忆的标记。    www.baidu.com
 *        	 DNS:域名解析系统,将域名和IP进行对应。 

 */
public class SocketDemo01 {
	public static void main(String[] args) {
		
	    //1.根据 IP地址和端口号创建套接字地址。InetSocketAddress(InetAddress addr, int port) 
		//"localhost"表示本机,127.0.0.1表示本机这个地址不可变。
		InetSocketAddress isa=new InetSocketAddress("www.baidu.com",8080);
		
		
		//2.获取地址             .getAddress()
		System.out.println(isa.getAddress());  //输出www.baidu.com/183.232.231.173
		
		//3.获取主机名/域名  .getHostName()  
		//注意:如果输入的地址是本机地址,那么返回的是计算机的主机名
		System.out.println(isa.getHostName()); //输出www.baidu.com
		
		
		//4.获取端口号          .getPort()
		System.out.println(isa.getPort());     //输出8080
		
		
		
		
		
	}
}
package SocketDemo;

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

/*
 * *2.UDP
 * 
 *    特点:
 *        底层基于流使用,不建立连接,不可靠,传输速度是相对比较快的。
 *        需要对数据进行封包,每个包不超过64K大小。
 *     
 *     适用:
 *     		适用于对速度依赖性比较强但是对可靠性依赖性比较低的场景。  ---视频,直播
 *     
 *     
 *3.   DatagramSocket     DatagramPacket
 *       先运行接收端,后进行发送端,接收端多个数据包的5.解析数据
 *     
 *     发送端:1.创建UDP套接字对象                                                                              ds=DatagramSocket()         
 *          2.准备数据包,并且将数据放入数据包中,并且绑定要发往的地址          dp=DatagramPacket(buf,length,address)
 *          3.发送数据包                                                 ds.send(dp)
 *          4.关流                                                       ds.close()
 *       
 *    
 *     接收端: 1.创建UDP套接字对象,并绑定端口号                                                        ds=DatagramSocket(Port);
		   2. 准备数据包 													 dp=DatagramPacket(byte[] buf, int length) 
		   3. 接收数据													 ds.receive(dp);
		   4. 关流														 ds.close();				
		   5. 解析数据												         数据包的底层数组byte[] bs=dp.getData();
		   														              数据的实际大小int len=dp.getLength();
		   														          new String(bs,0,len);
 *        
 *        
 */

//UDP发送端
public class SocketDemo02UDPSend {
	public static void main(String[] args) throws IOException {
		
		//1.创建一个UDP套接字对象                      new DatagramSocket();
		DatagramSocket ds=new DatagramSocket();
		
		//2.准备数据包,并且将数据放入数据包 new DatagramPacket(buf.length,address);
		//buf:表示要发送的数据
		//length:表示发送的数据大小
		//address:表示要发送的地址
		DatagramPacket dp=new DatagramPacket("你好".getBytes(), "你好".getBytes().length, new InetSocketAddress("localhost",8080));
		
		
		//3.发送数据包    .send()
		ds.send(dp);
		
		//4.关流             .close()
		ds.close();
		
	}
}
package SocketDemo;

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



//UDP接收,先运行接收端,后进行发送端,接收端多个数据包的5.解析数据
/*
 *3.   DatagramSocket     DatagramPacket
 *       先运行接收端,后进行发送端
 *     
 *     发送端:1.创建UDP套接字对象                                                                              ds=DatagramSocket()         
 *          2.准备数据包,并且将数据放入数据包中,并且绑定要发往的地址          dp=DatagramPacket(buf,length,address)
 *          3.发送数据包                                                 ds.send(dp)
 *          4.关流                                                       ds.close()
 *       
 *    
 *     接收端: 1.创建UDP套接字对象,并绑定端口号                                                        ds=DatagramSocket(Port);
		   2. 准备数据包 													 dp=DatagramPacket(byte[] buf, int length) 
		   3. 接收数据													 ds.receive(dp);
		   4. 关流														 ds.close();				
		   5. 解析数据												         数据包的底层数组byte[] bs=dp.getData();
		   														              数据的实际大小int len=dp.getLength();
		   														          new String(bs,0,len);
 *        
 */


//UDP接收端
public class SocketDemo02UDPReceive {
	public static void main(String[] args) throws IOException {
		//1.创建一个UDP套接字对象,绑定端口号                    new DatagramSocket(port);
		DatagramSocket ds=new DatagramSocket(8080);
		
		//2.用来接收长度为length的数据包。                     DatagramPacket(byte[] buf, int length) 
		DatagramPacket dp=new DatagramPacket(new byte[1024],1024);
		
		
		//3.接收数据  .receive()
		ds.receive(dp);
		System.out.println("接收成功");
		
		//4.关流         .close()
		ds.close();
		
		
		//5.将数据从数据包中解析出来            
		//5.1获取数据包的底层数组
		byte[] bs=dp.getData();
		//5.2获取数据的实际大小
		int len=dp.getLength();                 
		System.out.println(new String(bs,0,len));
		
		
		//获取发送过来的主机地址
		System.out.println(dp.getAddress());
		//获取发送过来的端口号
		System.out.println(dp.getPort());
		
	}
}
package SocketDemo;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketException;
import java.util.Scanner;

public class SocketUDPExer {
	public static void main(String[] args) {
		//练习1:一个线程表示发送端,另一个线程表示接收端---单人聊天
		new Thread(new UDPSend()).start();              
		new Thread(new UDPReceive()).start();
	}
}

/*
 *  发送端:  1.创建UDP套接字对象                                                                              ds=DatagramSocket()         
 *          2.准备数据包,并且将数据放入数据包中,并且绑定要发往的地址          dp=DatagramPacket(buf,length,address)
 *          3.发送数据包                                                 ds.send(dp)
 *          4.关流                                                       ds.close()
 */

//发送端
class UDPSend implements Runnable{
    private DatagramSocket ds;
    private DatagramPacket dp;
    private Scanner s;
   
    
    //构造代码块
    {
    	try {
    		//1.创建UDP套接字对象              ds=DatagramSocket()    
			ds=new DatagramSocket();
			//写入数据
			s=new Scanner(System.in);
		}catch (SocketException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    }
    
	@Override
	public void run() {
		// TODO Auto-generated method stub
		while(true) {                              
			//读取数据
			String msg=s.nextLine();                
			byte[] bs=msg.getBytes();
			
			//2.准备数据包,并且将数据放入数据包中,并且绑定要发往的地址       dp= DatagramPacket(buf,length,address)
			                                                         //改为255.255.255.255广播地址  可以多人聊天
			dp=new DatagramPacket(bs,bs.length,new InetSocketAddress("localhost",8080));
			
			try {
				//3.发送数据包            ds.send(dp)
				ds.send(dp);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}finally {
				
				// 4.关流     ds.close()
				ds.close();
			}
		}
	
	}
}

/*
 * 接收端:    1.创建UDP套接字对象,并绑定端口号                                                          ds=DatagramSocket(Port);
		   2. 准备数据包 													 dp=DatagramPacket(byte[] buf, int length) 
		   3. 接收数据													 ds.receive(dp);
		   4. 关流														 ds.close();				
		   5. 解析数据												         数据包的底层数组byte[] bs=dp.getData();
		   														              数据的实际大小int len=dp.getLength();
		   														          new String(bs,0,len);
 */


class UDPReceive implements Runnable{
    private DatagramSocket ds;
    //---------为什么这里可以直接创建--------------
	//2.用来接收长度为length的数据包。                     DatagramPacket(byte[] buf, int length) 
    private DatagramPacket dp=new DatagramPacket(new byte[1024],1024);
    
    {
    	try {
    		//1.创建一个UDP套接字对象,绑定端口号              new DatagramSocket(port);
			ds=new DatagramSocket(8080);
		} catch (SocketException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    }
	@Override
	public void run() {
		// TODO Auto-generated method stub
		try {
			while(true) {
				
			//3.接收数据  .receive()
			ds.receive(dp);
			
			
			//5.将数据从数据包中解析出来            
			//5.1获取数据包的底层数组  byte[] bs=dp.getData();
			//5.2获取数据的实际大小      int len=dp.getLength();  
			System.out.println(dp.getAddress()+":");
			
			byte[] bs=dp.getData();
			int len=dp.getLength();                 
			System.out.println(new String(bs,0,len));
			//等价于System.out.println(new String(dp.getData,0,dp.getLength()));
			}
			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{
			//4.关流         .close()
			ds.close();
		}
		
		
	}
	
}
package SocketDemo;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;



/*
 *3. TCP
 *
 *           基于流的,建立连接,经历三次握手,可靠,但是传输速率相对较慢,理论上不限制传输的数据的大小。
             适用于对可靠性的依赖性更高对速度依赖性较低的场景----文件传输
 *
 *  3.1三次握手;
 *              1.请求:		建立连接/发送数据          ->
 *       客户端     <- 2.确认:		可以建立连接/发送数据                  服务器
 *              3.再次确认: 收到信息,准备连接/发送  ->
 *              
 *              
 *   3.1注意:receive / connect/accept/write/read 都会产生阻塞
 *         扩展:BIO     Blocking IO           同步式阻塞式IO
 *         NIO    New IO-NonBlock  IO   同步式非阻塞式IO  JDK1.4
 *         AIO    Asynchronous     IO    异步式非阻塞式IO JDK1.8
 *              
 */

/*
 * TCP客户端:Socket
 * 			1.创建客户端的套接字对象sc=Socket()
 *           2.发起连接	          sc.connect()
 *           3.获取自带的输出流,写数据,写完禁用输出流                                  
 *           OutputStream out=sc.getOutputStream()  out.write(byte[])   sc.shutdownOutput();
 *           4.如果服务器端游打回的数据,需要获取输入流读取数据,禁用输入流  
 *            InputStream in=sc.getInputStream();   in.read(byte[])  sc.shutdownInput();
 *           5.关流               sc.close()
 *                 
 * 
 * 
 * TCP服务端:ServerSocket
 * 			1.创建服务器端的套接字对象,并且绑定监听的端口号  ss=ServerSocket(port)
 *          2.接受连接,获取到一个Socket对象                       Socket s=ss.accept()
 *          3.获取输入流,读取消息,读完禁用输入流 
 *          InputStream in=s.getInputStream();    in.read(byte[])    s.shutdownInput();
 *          4.如果需要向客户端发送消息,则需要获取输出流数据,禁用输出流
 *          s.getOutputStream().write("消息读取成功".getBytes());    s.shutdownOutput();
 *          5.关流             ss.close();
 */




public class SocketDemo03TCPClient {
	public static void main(String[] args) throws IOException {
		//1.创建客户端的套接字对象   sc=Socket()
		Socket sc=new Socket();
		
		
		//2.发起连接                              sc.connect(Address)   //手动阻塞时间,5秒钟连接不上,就拒绝连接
		sc.connect(new InetSocketAddress("localhost",8005),5000);
		
		
		
		//3.1获取Socket上的输出流
		OutputStream out= sc.getOutputStream();
		
		//3.2向服务器发送数据
		out.write("你好".getBytes());
		
		//3.3告诉服务器数据已经写出完毕
		sc.shutdownOutput();
		
		//4.接受服务器打回的消息
		InputStream in=sc.getInputStream();
		byte[] bs=new byte[1024];
		int len=-1;
		while((len=in.read(bs))!=-1) {
			System.out.println(new String(bs,0,len));
		}
		sc.shutdownInput();
		
		
		//5.关流
		sc.close();
		
	}
}
package SocketDemo;

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

/*
 * TCP客户端:Socket
 * 			1.创建客户端的套接字对象sc=Socket()
 *           2.发起连接	          sc.connect()
 *           3.获取自带的输出流,写数据,写完禁用输出流                                  
 *           OutputStream out=sc.getOutputStream()  out.write(byte[])   sc.shutdownOutput();
 *           4.如果服务器端游打回的数据,需要获取输入流读取数据,禁用输入流  
 *            InputStream in=sc.getInputStream();   in.read(byte[])  sc.shutdownInput();
 *           5.关流               sc.close()
 *                 
 * 
 * 
 * TCP服务端:ServerSocket
 * 			1.创建服务器端的套接字对象,并且绑定监听的端口号  ss=ServerSocket(port)
 *          2.接受连接,获取到一个Socket对象                       Socket s=ss.accept()
 *          3.获取输入流,读取消息,读完禁用输入流 
 *          InputStream in=s.getInputStream();    in.read(byte[])    s.shutdownInput();
 *          4.如果需要向客户端发送消息,则需要获取输出流数据,禁用输出流
 *          s.getOutputStream().write("消息读取成功".getBytes());    s.shutdownOutput();
 *          5.关流             ss.close();
 */


public class SocketDemo03TCPServer {
	public static void main(String[] args) throws IOException {
		//1.创建服务器端的套接字对象,绑定端口号
		ServerSocket ss=new ServerSocket(8005);
		
		//2.接受连接
		//产生阻塞
		Socket s=ss.accept();
		
		//3.1获取Socket自带的输入流
		InputStream in=s.getInputStream();
		
		//3.2读取客户端发来的数据
		byte[] bs=new byte[1024];
		int len=-1;
		while((len=in.read(bs))!=-1) {
			System.out.println(new String(bs,0,len));
		}
		
		//3.3通知客户端数据读取完毕
		s.shutdownInput();
		
		//4.向客户端打回一条消息
		s.getOutputStream().write("消息读取成功".getBytes());
		s.shutdownOutput();
	
		
		//5.关流
		ss.close();
	}
}
package SocketDemo;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;

//练习1.采用TCP上传文件
//客户端读取文件并将读取的内容传到服务器端
//在服务器端接收数据然后将接收的数据写到相应文件


/*
 * TCP客户端:Socket
 * 			1.创建客户端的套接字对象sc=Socket()
 *           2.发起连接	          sc.connect()
 *           3.获取自带的输出流,写数据,写完禁用输出流                                  
 *           OutputStream out=sc.getOutputStream()  out.write(byte[])   sc.shutdownOutput();
 *           4.如果服务器端游打回的数据,需要获取输入流读取数据,禁用输入流  
 *            InputStream in=sc.getInputStream();   in.read(byte[])  sc.shutdownInput();
 *           5.关流               sc.close()
 *                 
 * 
 */

/*
 * 	如果文件名的字节个数超过了一个字节所能表示的范围,那么这个时候可以用2个字节传输所表示文件名的字节个数
	byte n = (byte)(len / 256); // 确定文件名中有几个完整的字节  
	byte left = (byte)(len % 256 - 128); // 去掉完整字节之后的剩余的可以传输的字节个数
	读取的时候通过
	int len = n * 256 + left + 128; 从而表示完整的全部文件名占用的字节个数

 */


public class SocketTCPExerClient {
	public static void main(String[] args) throws IOException {
	
		//1.创建客户端的套接字对象
		Socket sc=new Socket();
	
		//2.发起连接                                                                        //手动阻塞时间,5秒钟连接不上,就拒绝连接
		sc.connect(new InetSocketAddress("localhost",8010),5000);
		
		//3.获取Socket上的输出流
		OutputStream out= sc.getOutputStream();

//-----------只需要改这一步-----------之前是out.write("你好".getBytes());-----------------	
		//4.向服务器发送数据
		
		//4.1获取文件的名字和类型,并写出
		File file=new File("C:\\Users\\123\\Desktop\\0317笔记.docx");
		byte[] filename =file.getName().getBytes();
		
		out.write(filename.length-128);  //先写文件名长度   9  00001001  26 00011001 可以一个字节表示文件名长度
		out.write(filename);            //再写文件名
		
		//4.2读取文件内容,并写出
		FileInputStream in2=new FileInputStream(file);
		byte[] bytes=new byte[10];      
		int length=-1; 
		while((length=in2.read(bytes))!=-1) {
			out.write(bytes,0,length);
		}
		in2.close();
		
		
		//5.告诉服务器数据已经写出完毕
		sc.shutdownOutput();
		
		//6.关流
		sc.close();
		
		
	}
}


package SocketDemo;

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

/* TCP服务端:ServerSocket
* 		   1.创建服务器端的套接字对象,并且绑定监听的端口号  ss=ServerSocket(port)
*          2.接受连接,获取到一个Socket对象                       Socket s=ss.accept()
*          3.获取输入流,读取消息,读完禁用输入流 
*          InputStream in=s.getInputStream();    in.read(byte[])    s.shutdownInput();
*          4.如果需要向客户端发送消息,则需要获取输出流数据,禁用输出流
*          s.getOutputStream().write("消息读取成功".getBytes());    s.shutdownOutput();
*          5.关流             ss.close();
*/


/*
 * 	如果文件名的字节个数超过了一个字节所能表示的范围,那么这个时候可以用2个字节传输所表示文件名的字节个数
	byte n = (byte)(len / 256); // 确定文件名中有几个完整的字节  
	byte left = (byte)(len % 256 - 128); // 去掉完整字节之后的剩余的可以传输的字节个数
	读取的时候通过
	int len = n * 256 + left + 128; 从而表示完整的全部文件名占用的字节个数

 */


public class SocketTCPExerServer {
	public static void main(String[] args) throws IOException {
		//1.创建服务器端的套接字对象,绑定端口号
		ServerSocket ss=new ServerSocket(8010);
		
		//2.接受连接
		//产生阻塞
		Socket s=ss.accept();
		
		//3.获取Socket自带的输入流
		InputStream in=s.getInputStream();
		
//-----------只需要改这一步--------------------
		/*
		 * 之前是
		 *      byte[] bs=new byte[1024];
			    int len=-1;
				while((len=in.read(bs))!=-1) {
					System.out.println(new String(bs,0,len));
				}		
		 */
		
		//4.读取客户端发来的数据
		
		//读取文件名的长度
		byte len=(byte)in.read();  //先读一次,就读一个字节,读取文件名长度
		
		byte[] name=new byte[len+128];  //文件名长度为每次读取的长度
		in.read(name);       //再读一次,读取文件名
		
		FileOutputStream out2=new FileOutputStream("C:\\Users\\123\\Tarena\\"+new String(name));
		byte[] bs2=new byte[1024];
		int len2=-1;
		while((len2=in.read(bs2))!=-1) {
			out2.write(bs2,0,len2);
		}
		out2.close();
		
		
		//5.通知客户端数据读取完毕
		s.shutdownInput();
	
		//6.关流
		ss.close();
	}
}
package JDK5;
/*
 * JDK1.5的特性
   1.自动封箱/拆箱 
   2.增强for循环
   3.静态导入 
   4.可变参数 
   5.枚举 
   6.泛型 
   7.反射(JDK1.4出现,1.5增强)
   8. 动态代理 
   9.内省 
   10.注解
   
 */


//可变参数 ...
//1.可变参数,允许传入的参数个数随意变换 
//2.可变参数本质上是数组     int... is=int[] is
//3.可变参数可以传入0-多个参数
//4.一个方法中只能定义一个可变参数,这唯一的一个可变参数必须定义到参数列表的末尾



public class VariableDemo {
	public static void main(String[] args) {
		//System.out.println(add(new int[] {2,4,6,5,8}));
		
		//任意数目的数字求和
		//3.可变参数可以传入0-多个参数
		System.out.println(add());   //不传值是0,默认为0
		System.out.println(add(6));
		System.out.println(add(6,8));
		System.out.println(add(6,8,98,9,6,5,6,8,9,4));
	}
	
	   
	   //1.可变参数,允许传入的参数个数随意变换 
		public static int add(int... is) {  //4.一个方法中只能定义一个可变参数,这唯一的一个可变参数必须定义到参数列表的末尾
			int sum=0;
			for(int i=0;i<is.length;i++) {  //2.可变参数本质上是数组     int... is=int[] is
				sum+=is[i];
			}
			return sum;
		}
	
	
		
	/*
	
	
	
	//注意:2个整数和3个整数求和代码与10个数组功能冗余。
	
	//2个整数求和
	public static int add(int i,int j) {
		return i+j;
	}
	//3个整数求和
	public static int add(int i,int j,int k) {
		return i+j+k;
	}
	
	
	
	//10个整数求和
	public static int add(int[] arr) {
		int sum=0;
		for(int i:arr) {
			sum+=i;
		}
		return sum;
	}
	*/
	
	
}
package JDK5;
/*
 * JDK1.5的特性
   1.自动封箱/拆箱 
   2.增强for循环
   3.静态导入 
   4.可变参数 
   5.枚举 
   6.泛型 
   7.反射(JDK1.4出现,1.5增强)
   8. 动态代理 
   9.内省 
   10.注解
   
 */

//5.枚举 ---------没写完--------------
//      1.取值相对固定并且能够一一列举。
//		2.用enum定义枚举,枚举本身就是一个类
//      3.枚举类中的构造方法默认私有,枚举常量必须定义在枚举类的首行
//      4.枚举类中定义任意类型的方法和属性,包括抽象方法
//		 
 //		5.在Java中,所有的枚举默认继承java.lang.Enum
//		6.JDK1.5开始,允许在switch-case中使用枚举常量
public class EnumDemo {
	public static void main(String[] args) {
		Seasons s=Seasons.Spring;
		//s.say();
		
		//6.JDK1.5中,允许在switch-case中使用
		switch(s) {
			case Spring:
				System.out.println("春天");
				break;
			case Summer:
				System.out.println("夏天");
				break;
			case Autumn:
				System.out.println("秋天");
				break;
			case Winter:
				System.out.println("冬天");
				break;
			default :
				break;
				
		}
		
	}
}

//枚举,本身是类
enum Seasons{
	//3.枚举中的构造方法默认私有化   private Seasons(){}
	Spring,Summer,Autumn,Winter;//3.枚举常量,且必须定义定义在枚举类的首行
	
	
	//4.可以在枚举类提供任意属性和方法
	private int[] months;
	private int year;
	
	public int getYear() {
		return year;
	}
	public void setYear(int year) {
		this.year = year;
	}
	
	//4.可以定义抽象方法,只是枚举常量变为匿名内部类
	
	/*
	 //构造方法可以重载
	 private int year;
	 private Seasons() {
	}

	private Seasons(int year) {
		this.year = year;
	}
	 
	 
	public abstract void Say() {
		System.out.println("抽象方法");
	}
	
	
	将枚举常量变为匿名内部类
	 Sping(256){            //构造方法重载传入参数
		@Override
		public void Say() {
			// TODO Auto-generated method stub
			
		}
	};  
	*/
}

//无枚举之前
class Season{
	private Season() {}
	public static final Season Spring=new Season();
	public static final Season Summer=new Season();
	public static final Season Autumn=new Season();
	public static final Season Winter=new Season();
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值