JAVA入门到精通-网络编程补充和QQ案例

------------------------------------------------------

补充讲解:

如何在网络间传递对象?

[MyServer.java]服务器源代码

package com.test.server; import java.io.ObjectInputStream; import java.net.ServerSocket; import java.net.Socket; import com.common.User; public class MyServer { ServerSocket ss; Socket s; ObjectInputStream ois; public static void main(String[] args) { new MyServer(); } //构造函数 public MyServer(){ try { ss=new ServerSocket(3456); s=ss.accept(); //以对象流的方式读取(假设客户端发送的是User的一个对象) ois=new ObjectInputStream(s.getInputStream()); User u=(User)ois.readObject(); //输出 System.out.println(u.getName()+"\t"+u.getPasswd()); } catch (Exception e) { e.printStackTrace(); }finally{ try { if(ois!=null) ois.close(); if(s!=null) s.close(); if(ss!=null) ss.close(); } catch (Exception e2) { e2.printStackTrace(); } } } }
39
39
 
1
package com.test.server;
2
import java.io.ObjectInputStream;
3
import java.net.ServerSocket;
4
import java.net.Socket;
5
import com.common.User;
6
 
7
public class MyServer {
8
    ServerSocket ss;
9
    Socket s;
10
    ObjectInputStream ois;
11
   
12
    public static void main(String[] args) {
13
        new MyServer();
14
    }
15
   
16
    //构造函数
17
    public MyServer(){
18
        try {
19
            ss=new ServerSocket(3456);
20
            s=ss.accept();
21
            //以对象流的方式读取(假设客户端发送的是User的一个对象)
22
            ois=new ObjectInputStream(s.getInputStream());
23
            User u=(User)ois.readObject();
24
            //输出
25
            System.out.println(u.getName()+"\t"+u.getPasswd());
26
           
27
        } catch (Exception e) {
28
            e.printStackTrace();
29
        }finally{
30
            try {
31
                if(ois!=null) ois.close();
32
                if(s!=null) s.close();
33
                if(ss!=null) ss.close();
34
            } catch (Exception e2) {
35
                e2.printStackTrace();
36
            }
37
        }
38
    }
39
}

[User.java]服务端的公共服务

package com.common; import java.io.Serializable; public class User implements Serializable{ private String name; private String passwd; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPasswd() { return passwd; } public void setPasswd(String passwd) { this.passwd = passwd; } }
20
20
 
1
package com.common;
2
 
3
import java.io.Serializable;
4
 
5
public class User implements Serializable{
6
    private String name;
7
    private String passwd;
8
    public String getName() {
9
        return name;
10
    }
11
    public void setName(String name) {
12
        this.name = name;
13
    }
14
    public String getPasswd() {
15
        return passwd;
16
    }
17
    public void setPasswd(String passwd) {
18
        this.passwd = passwd;
19
    }
20
}

 

[MyClient.java]客户端源代码

package com.test.client; import java.io.ObjectOutputStream; import java.net.Socket; import com.common.User; public class MyClient { Socket s; ObjectOutputStream oos; public static void main(String[] args) { new MyClient(); } //构造函数 public MyClient(){ try { s=new Socket("127.0.0.1",3456); //通过ObjectOutputStream给服务器传送对象 oos=new ObjectOutputStream(s.getOutputStream()); User u=new User(); u.setName("张三"); u.setPasswd("123"); oos.writeObject(u); } catch (Exception e) { e.printStackTrace(); }finally{ try { if(oos!=null) oos.close(); if(s!=null) s.close(); } catch (Exception e2) { e2.printStackTrace(); } } } }
36
36
 
1
package com.test.client;
2
 
3
import java.io.ObjectOutputStream;
4
import java.net.Socket;
5
import com.common.User;
6
 
7
public class MyClient {
8
    Socket s;
9
    ObjectOutputStream oos;
10
   
11
    public static void main(String[] args) {
12
        new MyClient();
13
    }
14
 
15
    //构造函数
16
    public MyClient(){
17
        try {
18
            s=new Socket("127.0.0.1",3456);
19
            //通过ObjectOutputStream给服务器传送对象
20
            oos=new ObjectOutputStream(s.getOutputStream());
21
            User u=new User();
22
            u.setName("张三");
23
            u.setPasswd("123");
24
            oos.writeObject(u);
25
        } catch (Exception e) {
26
            e.printStackTrace();
27
        }finally{
28
            try {
29
                if(oos!=null) oos.close();
30
                if(s!=null) s.close();
31
            } catch (Exception e2) {
32
                e2.printStackTrace();
33
            }
34
        }
35
    }
36
}

 

[User.java]客户端的公共服务

package com.common; import java.io.Serializable; //通过io在网络上传送对象需要进行序列化Serializable public class User implements Serializable{ private String name; private String passwd; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPasswd() { return passwd; } public void setPasswd(String passwd) { this.passwd = passwd; } }
21
 
1
package com.common;
2
 
3
import java.io.Serializable;
4
//通过io在网络上传送对象需要进行序列化Serializable
5
public class User implements Serializable{
6
    private String name;
7
    private String passwd;
8
   
9
    public String getName() {
10
        return name;
11
    }
12
    public void setName(String name) {
13
        this.name = name;
14
    }
15
    public String getPasswd() {
16
        return passwd;
17
    }
18
    public void setPasswd(String passwd) {
19
        this.passwd = passwd;
20
    }
21
}

特别说明:

在java网络编程需要通过IO流实现对象的传递需要对,服务端和客户端定义相同的传递对对向方法,以达到实现对象的传递。同时需要对方法进行Serializable序列化,否则报错。


------------------------------


QQ
案例

说明:该案例主讲内容:java网络编程、多线程、C/S数据交互

附源代码

注:代码分为Server部分与Client部分,由于此案例仅为对NET操作未使用数据库

Server部分包含的包有:

1、com.qq.server.view (服务端界面包)

1.1、QqServerFrame.java (服务端主页面)

2、com.qq.server.model (业务逻辑包)

2.1、MyQqServer.java (服务器验证客户信息)

2.2、QqServerUser.java (用于管理QQ用户信息[此包功能应为对数据库逻辑操作])(空)

2.3、SerConClientThread.java (服务器连接客户端线程)

2.4、ManageClientThrea.java (管理客户端连接线程)

3、com.qq.server.db (数据库操作包)

   3.1、SqlHelper.java (对数据库的CURD操作)(空)

4、com.qq.server.tools (服务端工具包)(空)

5、com.qq.common (通用包)

   5.1、Message.java (消息类)

   5.2、MessageType.java (消息类型接口类)

   5.3、User.java (用户信息类)

Client部分包含的包有:

1、com.qq.client.view (客户端界面包)

1.1、QqClientLogin.java (QQ登录界面)

1.2、QqFriendList.java (好友列表界面)

1.3、QqChat.java (聊天界面)

2、com.qq.client.model (客户端业务逻辑包)

2.1、QqClienConServer.java (客户端连接服务端的后台用于与服务端数据交互)

2.2、QqClientUser.java (客户端用户操作逻辑类)

3、com.qq.client.tools (原应为客户端工具包,现为处理与服务端的线程包)

   3.1、ClientConServerThread.java (客户端连接服务器线程类)

   3.2、ManageClientConServerThread.java (管理C/S线程类)

   3.3、ManageQqChat.java (管理聊天界面类)

   3.4、ManageQqFriendList.java (管理好友列表类)

4、com.qq.common (通用包)

   4.1、Message.java (消息类)

   4.2、MessageType.java(消息类型类)

   4.3、User.java (用户信息类)

注意:Server与Client中的com.qq.common通用包主要功能是统一保持客户端与服务端的用户及消息一致。

 

下见源代码:

 

 

Server端源代码:

com.qq.server.view

[QqServerFrame.java]

/** * 服务器端的控制界面 * 功能: * 1、完成启动、关闭服务器 * 2、管理及监控用户 */ package com.qq.server.view; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import com.qq.server.model.MyQqServer; public class QqServerFrame extends JFrame implements ActionListener{ JPanel jp1; JButton jb1,jb2; public static void main(String []args){ new QqServerFrame(); } //构造函数 public QqServerFrame(){ jp1=new JPanel(); jb1=new JButton("启动服务器"); jb1.addActionListener(this); jb2=new JButton("关闭服务器"); jb2.addActionListener(this); jp1.add(jb1); jp1.add(jb2); this.add(jp1); this.setSize(500, 400); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setVisible(true); } @Override public void actionPerformed(ActionEvent e) { if(e.getSource()==jb1){ new MyQqServer(); }else if(e.getSource()==jb2){ System.exit(0); } } }
48
 
1
/**
2
 * 服务器端的控制界面
3
 * 功能:
4
 *     1、完成启动、关闭服务器
5
 *     2、管理及监控用户
6
 */
7
package com.qq.server.view;
8
 
9
import java.awt.event.ActionEvent;
10
import java.awt.event.ActionListener;
11
import javax.swing.JButton;
12
import javax.swing.JFrame;
13
import javax.swing.JPanel;
14
import com.qq.server.model.MyQqServer;
15
 
16
public class QqServerFrame extends JFrame implements ActionListener{
17
    JPanel jp1;
18
    JButton jb1,jb2;
19
   
20
    public static void main(String []args){
21
        new QqServerFrame();
22
    }
23
   
24
    //构造函数
25
    public QqServerFrame(){
26
        jp1=new JPanel();
27
        jb1=new JButton("启动服务器");
28
        jb1.addActionListener(this);
29
        jb2=new JButton("关闭服务器");
30
        jb2.addActionListener(this);
31
        jp1.add(jb1);
32
        jp1.add(jb2);
33
       
34
        this.add(jp1);
35
        this.setSize(500, 400);
36
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
37
        this.setVisible(true);
38
    }
39
 
40
    @Override
41
    public void actionPerformed(ActionEvent e) {
42
        if(e.getSource()==jb1){
43
            new MyQqServer();
44
        }else if(e.getSource()==jb2){
45
            System.exit(0);
46
        }
47
    }
48
}

*******************************************************************************

com.qq.server.model

[MyQqServer.java]

/** * 这是QQ服务器,它在监听等待某个QQ客户端连接服务器 */ package com.qq.server.model; import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.net.ServerSocket; import java.net.Socket; import com.qq.common.Message; import com.qq.common.User; public class MyQqServer { BufferedReader br; public MyQqServer(){ try { System.out.println("服务器在监听9999端口..."); //在9999端口监听 ServerSocket ss=new ServerSocket(9999); //等待连接 while(true){ Socket s=ss.accept(); //接收客户端发来的信息 ObjectInputStream ois=new ObjectInputStream(s.getInputStream()); User u=(User)ois.readObject(); Message m=new Message(); ObjectOutputStream oos=new ObjectOutputStream(s.getOutputStream()); //此处代替数据库密码验证 if(u.getPasswd().equals("12345")){ //返回一个成功登录的信息包 m.setMesType("1"); oos.writeObject(m); //这里就单开一个线程,让该线程与该客户端保持通讯 SerConClientThread scct=new SerConClientThread(s); ManageClientThrea.addClientThrea(u.getUserId(), scct); //启动与该客户端通讯的线程 scct.start(); //并通知其它在线用户 scct.notifyOther(u.getUserId()); }else{ m.setMesType("2"); oos.writeObject(m); //关闭连接 s.close(); } } } catch (Exception e) { e.printStackTrace(); } } }
55
 
1
/**
2
 * 这是QQ服务器,它在监听等待某个QQ客户端连接服务器
3
 */
4
package com.qq.server.model;
5
 
6
import java.io.BufferedReader;
7
import java.io.InputStreamReader;
8
import java.io.ObjectInputStream;
9
import java.io.ObjectOutputStream;
10
import java.net.ServerSocket;
11
import java.net.Socket;
12
import com.qq.common.Message;
13
import com.qq.common.User;
14
 
15
public class MyQqServer {
16
    BufferedReader br;
17
 
18
    public MyQqServer(){
19
        try {
20
            System.out.println("服务器在监听9999端口...");
21
            //在9999端口监听
22
            ServerSocket ss=new ServerSocket(9999);
23
            //等待连接
24
            while(true){
25
                Socket s=ss.accept();
26
                //接收客户端发来的信息
27
                ObjectInputStream ois=new ObjectInputStream(s.getInputStream());
28
                User u=(User)ois.readObject();
29
                Message m=new Message();
30
                ObjectOutputStream oos=new ObjectOutputStream(s.getOutputStream());
31
                //此处代替数据库密码验证
32
                if(u.getPasswd().equals("12345")){
33
                    //返回一个成功登录的信息包
34
                    m.setMesType("1");
35
                    oos.writeObject(m);
36
                    //这里就单开一个线程,让该线程与该客户端保持通讯
37
                    SerConClientThread scct=new SerConClientThread(s);
38
                    ManageClientThrea.addClientThrea(u.getUserId(), scct);
39
                    //启动与该客户端通讯的线程
40
                    scct.start();
41
                   
42
                    //并通知其它在线用户
43
                    scct.notifyOther(u.getUserId());
44
                }else{
45
                    m.setMesType("2");
46
                    oos.writeObject(m);
47
                    //关闭连接
48
                    s.close();
49
                }
50
            }
51
        } catch (Exception e) {
52
            e.printStackTrace();
53
        }
54
    }
55
}

*******************************************************************************

[SerConClientThread.java]

/** * 功能:是服务器与某个客户端的通讯线程 */ package com.qq.server.model; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.net.Socket; import java.util.HashMap; import java.util.Iterator; import com.qq.common.Message; import com.qq.common.MessageType; public class SerConClientThread extends Thread{ Socket s; public SerConClientThread(Socket s){ //把服务器与该客户端的连接赋给s this.s=s; } //让该线程去通知其它在线用户 public void notifyOther(String iam){ //得到所有在线的用户的线程 HashMap hm=ManageClientThrea.hm; Iterator it=hm.keySet().iterator(); while(it.hasNext()){ Message m=new Message(); m.setCon(iam); m.setMesType(MessageType.message_ret_onLineFriend); //取出在线用户的id String onLineUserId=it.next().toString(); try { ObjectOutputStream oos=new ObjectOutputStream(ManageClientThrea.getClientThrea(onLineUserId).s.getOutputStream()); m.setGetder(onLineUserId); oos.writeObject(m); } catch (IOException e) { e.printStackTrace(); } } } public void run(){ while(true){ //这里该线程就可以接收客户端发来的信息 try { ObjectInputStream ois=new ObjectInputStream(s.getInputStream()); Message m=(Message)ois.readObject(); System.out.println(m.getSender()+" 给 "+m.getGetder()+" 说:"+m.getCon()); //对从客户端取得的消息进行类型判断,然后做相应的处理 if(m.getMesType().equals(MessageType.message_comm_mes)){ //服务器完成转发功能 //取得接收人的通讯线程 SerConClientThread sc=ManageClientThrea.getClientThrea(m.getGetder()); ObjectOutputStream oos=new ObjectOutputStream(sc.s.getOutputStream()); oos.writeObject(m); }else if(m.getMesType().equals(MessageType.message_get_onLineFriend)){ //把在服务器的好友给该客户端返回 String res=ManageClientThrea.getAllOnLineUserid(); Message m2=new Message(); m2.setMesType(MessageType.message_ret_onLineFriend); m2.setCon(res); m2.setGetder(m.getSender()); ObjectOutputStream oos=new ObjectOutputStream(s.getOutputStream()); oos.writeObject(m2); } } catch (Exception e) { e.printStackTrace(); } } } }
75
 
1
/**
2
 * 功能:是服务器与某个客户端的通讯线程
3
 */
4
package com.qq.server.model;
5
 
6
import java.io.IOException;
7
import java.io.ObjectInputStream;
8
import java.io.ObjectOutputStream;
9
import java.net.Socket;
10
import java.util.HashMap;
11
import java.util.Iterator;
12
import com.qq.common.Message;
13
import com.qq.common.MessageType;
14
 
15
public class SerConClientThread extends Thread{
16
        Socket s;
17
   
18
    public SerConClientThread(Socket s){
19
        //把服务器与该客户端的连接赋给s
20
        this.s=s;
21
    }
22
   
23
    //让该线程去通知其它在线用户
24
    public void notifyOther(String iam){
25
        //得到所有在线的用户的线程
26
        HashMap hm=ManageClientThrea.hm;
27
        Iterator it=hm.keySet().iterator();
28
        while(it.hasNext()){
29
            Message m=new Message();
30
            m.setCon(iam);
31
            m.setMesType(MessageType.message_ret_onLineFriend);
32
            //取出在线用户的id
33
            String onLineUserId=it.next().toString();
34
            try {
35
                ObjectOutputStream oos=new ObjectOutputStream(ManageClientThrea.getClientThrea(onLineUserId).s.getOutputStream());
36
                m.setGetder(onLineUserId);
37
                oos.writeObject(m);
38
            } catch (IOException e) {
39
                e.printStackTrace();
40
            }
41
        }
42
    }
43
   
44
    public void run(){
45
        while(true){
46
            //这里该线程就可以接收客户端发来的信息
47
            try {
48
                ObjectInputStream ois=new ObjectInputStream(s.getInputStream());
49
                Message m=(Message)ois.readObject();
50
               
51
                System.out.println(m.getSender()+" 给 "+m.getGetder()+" 说:"+m.getCon());
52
               
53
                //对从客户端取得的消息进行类型判断,然后做相应的处理
54
                if(m.getMesType().equals(MessageType.message_comm_mes)){
55
                    //服务器完成转发功能
56
                    //取得接收人的通讯线程
57
                    SerConClientThread sc=ManageClientThrea.getClientThrea(m.getGetder());
58
                    ObjectOutputStream oos=new ObjectOutputStream(sc.s.getOutputStream());
59
                    oos.writeObject(m);
60
                }else if(m.getMesType().equals(MessageType.message_get_onLineFriend)){
61
                    //把在服务器的好友给该客户端返回
62
                    String res=ManageClientThrea.getAllOnLineUserid();
63
                    Message m2=new Message();
64
                    m2.setMesType(MessageType.message_ret_onLineFriend);
65
                    m2.setCon(res);
66
                    m2.setGetder(m.getSender());
67
                    ObjectOutputStream oos=new ObjectOutputStream(s.getOutputStream());
68
                    oos.writeObject(m2);
69
                }
70
            } catch (Exception e) {
71
                e.printStackTrace();
72
            }
73
        }
74
    }
75
}

*******************************************************************************

[ManageClientThrea.java]

/** * 这是一个管理客户端线程的类 */ package com.qq.server.model; import java.util.HashMap; import java.util.Iterator; public class ManageClientThrea { public static HashMap hm=new HashMap<String,SerConClientThread>(); //向hashmap中添加一个客户端通讯线程 public static void addClientThrea(String uid,SerConClientThread scct){ hm.put(uid,scct); } public static SerConClientThread getClientThrea(String uid){ return (SerConClientThread)hm.get(uid); } //返回当前在线的人的好友情况 public static String getAllOnLineUserid(){ //使用迭代器完成 Iterator it=hm.keySet().iterator(); String res=""; while(it.hasNext()){ res+=it.next().toString()+" "; } return res; } }
30
 
1
/**
2
 * 这是一个管理客户端线程的类
3
 */
4
package com.qq.server.model;
5
 
6
import java.util.HashMap;
7
import java.util.Iterator;
8
 
9
public class ManageClientThrea {
10
    public static HashMap hm=new HashMap<String,SerConClientThread>();
11
    //向hashmap中添加一个客户端通讯线程
12
    public static void addClientThrea(String uid,SerConClientThread scct){
13
        hm.put(uid,scct);
14
    }
15
   
16
    public static SerConClientThread getClientThrea(String uid){
17
        return (SerConClientThread)hm.get(uid);
18
    }
19
   
20
    //返回当前在线的人的好友情况
21
    public static String getAllOnLineUserid(){
22
        //使用迭代器完成
23
        Iterator it=hm.keySet().iterator();
24
        String res="";
25
        while(it.hasNext()){
26
            res+=it.next().toString()+" ";
27
        }
28
        return res;
29
    }
30
}

*******************************************************************************

com.qq.common

[Message.java]

/** * 为Message规定规则 * mesType1-->表明登录成功 * mesType2-->表明登录失败 * mesType3-->表明普通消息包 */ package com.qq.common; import java.io.Serializable; public class Message implements Serializable{ private String mesType; private String sender; private String getder; private String con; private String sendTime; public String getGetder() { return getder; } public void setGetder(String getder) { this.getder = getder; } public String getSender() { return sender; } public void setSender(String sender) { this.sender = sender; } public String getCon() { return con; } public void setCon(String con) { this.con = con; } public String getSendTime() { return sendTime; } public void setSendTime(String sendTime) { this.sendTime = sendTime; } public String getMesType() { return mesType; } public void setMesType(String mesType) { this.mesType = mesType; } }
57
 
1
/**
2
 * 为Message规定规则
3
 * mesType1-->表明登录成功
4
 * mesType2-->表明登录失败
5
 * mesType3-->表明普通消息包
6
 */
7
package com.qq.common;
8
 
9
import java.io.Serializable;
10
 
11
public class Message implements Serializable{
12
    private String mesType;
13
    private String sender;
14
    private String getder;
15
    private String con;
16
    private String sendTime;
17
 
18
    public String getGetder() {
19
        return getder;
20
    }
21
 
22
    public void setGetder(String getder) {
23
        this.getder = getder;
24
    }
25
 
26
    public String getSender() {
27
        return sender;
28
    }
29
 
30
    public void setSender(String sender) {
31
        this.sender = sender;
32
    }
33
 
34
    public String getCon() {
35
        return con;
36
    }
37
 
38
    public void setCon(String con) {
39
        this.con = con;
40
    }
41
 
42
    public String getSendTime() {
43
        return sendTime;
44
    }
45
 
46
    public void setSendTime(String sendTime) {
47
        this.sendTime = sendTime;
48
    }
49
 
50
    public String getMesType() {
51
        return mesType;
52
    }
53
 
54
    public void setMesType(String mesType) {
55
        this.mesType = mesType;
56
    }
57
}

*******************************************************************************

[MessageType.java]

/** * 定义消息包的种类的接口 */ package com.qq.common; public interface MessageType { String message_succeed="1";//登录成功包 String message_login_fail="2";//登录失败包 String message_comm_mes="3";//普通消息包 String message_get_onLineFriend="4";//要求在线的好友包 String message_ret_onLineFriend="5";//返回在线好友包 }
12
 
1
/**
2
 * 定义消息包的种类的接口
3
 */
4
package com.qq.common;
5
 
6
public interface MessageType {
7
    String message_succeed="1";//登录成功包
8
    String message_login_fail="2";//登录失败包
9
    String message_comm_mes="3";//普通消息包
10
    String message_get_onLineFriend="4";//要求在线的好友包
11
    String message_ret_onLineFriend="5";//返回在线好友包
12
}

*******************************************************************************

[User.java]

/** * 这是用户信息类 */ package com.qq.common; import java.io.Serializable; public class User implements Serializable{ private String userId; private String passwd; public String getUserId() { return userId; } public void setUserId(String userId) { this.userId = userId; } public String getPasswd() { return passwd; } public void setPasswd(String passwd) { this.passwd = passwd; } }
25
 
1
/**
2
 * 这是用户信息类
3
 */
4
package com.qq.common;
5
 
6
import java.io.Serializable;
7
 
8
public class User implements Serializable{
9
    private String userId;
10
    private String passwd;
11
    public String getUserId() {
12
        return userId;
13
    }
14
    public void setUserId(String userId) {
15
        this.userId = userId;
16
    }
17
    public String getPasswd() {
18
        return passwd;
19
    }
20
    public void setPasswd(String passwd) {
21
        this.passwd = passwd;
22
    }
23
}
24
 
          
25
 
          





转载于:https://www.cnblogs.com/xuxaut-558/p/10047898.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值