2017-04-01-网络通讯
Xplorist Lv6

2017-04-01-网络通讯

知识点1:

tcp/ip协议

知识点2:

TCP

UDP

socket

知识点模型总结:

网络通讯主要内容是计算机之间的交换数据

首先要通过物理连接计算机,再次多个计算机如何区分网络中的每台计算机,于是就产生了地址IP,计算机通讯是通过软件来执行的,多个软件都能够实现通信功能,到底信息要交个哪个软件处理,为了区分不同的通讯软件,于是就产生了端口。

URL类和URLConnection类,某个网路资源的路径来带代表这个路径上的资源,URLConnection代表连接连接对象,通过连接对象来传输数据

TCP(流式socket)

客户端发送请求到服务器,

(客户端的socket通过指定服务器的ip地址和接收软件的端口号寻找服务器和接收软件,socket再打开输出流,将socket通过流的方式发送出去)

服务器收到到请求,并给客户端发送响应

(服务器监听某一个端口收到请求并将收到的socket存进一个socket,再将这个socket打开输入流,将soicket中的内容读取到服务器软件中,服务器将要响应的消息通过socket打开输出流,将socket发送到客户端)

客户端得到响应

(客户端通过socket打开输入流将服务器的数据接收)

(整个过程中都是socket在传来传去)

UDP(数据包socket)

发送端将要发送的数据打包,并指定要发送的内容和要发送的的位置(ip和端口号)

通过DatagramSocket来将数据包发送出去

接收端通过DatagramSocket来接收数据包,并将数据包存进到接收端的数据包里,然后再处理

实例1:

线程最大数:
2017-04-01-01.png

实例2:

url
2017-04-01-02.png

实例3:

寻找内网中所有的ip

2017-04-01-03.png
2017-04-01-04.png

实例4:

客户端给服务器发送消息,

核心代码:

服务器:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
package com.share.demo04_01_网络通讯;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.util.Scanner;

public class Server {
    public static void main(String[] args) {
        // TODO Auto-generated meshod stub
        boolean bool = true;
        Scanner sc = new Scanner(System.in);
        try {
            // 创建一个ServerSocket监听8081端口
            ServerSocket server = new ServerSocket(8082);
            // server.setSoTimeout(10);// 设置连接超时时间为10秒
            while (bool) {
                // 等待请求
                Socket socket = server.accept();// 等待客户机的访问
                // 接收到请求后使用socket进行通信,创建BufferedReader用于读取数据
                BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                // System.out.println(socket.getInetAddress());
                String line = br.readLine();
                System.out.println("服务端收到的消息:::" + line);
                // 创建PrintWriter.用于发送数据
                PrintWriter pw = new PrintWriter(socket.getOutputStream());
                pw.println("反馈的信息:" + sc.next());
                pw.flush();
                pw.close();
                br.close();
                socket.close();
            }
            server.close();
        } catch (SocketTimeoutException e) {
            System.out.println("连接超时");
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

客户端:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
package com.share.demo04_01_网络通讯;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;

public class ClientTest {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Scanner sc = new Scanner(System.in);
        boolean bool = true;
        while (bool) {
            try {
                // 创建Socket,跟本机的8082端口相连
                Socket socket = new Socket("172.18.6.3", 8082);
                StringBuffer sb = new StringBuffer();
                InetAddress netAddress = socket.getInetAddress();// 获得远程服务器的地址
                String netIp = netAddress.getHostAddress();// 获得远程服务器的IP地址
                int netPort = socket.getPort();// 获得远程服务器的端口号
                InetAddress localAddress = socket.getLocalAddress();// 获得客户端的地址
                String localIp = localAddress.getHostAddress();// 获得客户端的IP地址
                int localPort = socket.getLocalPort();// 获得客户端的端口号
                sb.append("远程服务器的IP地址:" + netIp + "\n");
                sb.append("远程服务器的端口号:" + netPort + "\n");
                sb.append("客户机本地的IP地址:" + localIp + "\n");
                sb.append("客户机本地的端口号:" + localPort + "\n");
                System.out.println(sb.toString());
                // 使用Socket创建PrintWriter和BufferedReader进行读写数据
                PrintWriter pw = new PrintWriter(socket.getOutputStream());
                // 发送数据
                pw.println(sc.next());
                pw.flush();

                // 接收数据
                BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                String line = br.readLine();
                System.out.println("从服务器 返回的消息:::" + line);
                // 关闭资源
                pw.close();
                br.close();
                socket.close();

            } catch (UnknownHostException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }
    }
}

实例5:

tcp实例

客户端发送获取服务器中存储的内容的请求,

服务器获得客户端的请求并发送响应给客户端,

客户端获得服务器发送的消息

核心代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package com.share.eg01_TCP;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;

public class TCPClient {
    public static void main(String[] args) {
        try {
            test();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public static void test() throws Exception{
        Socket socket=new Socket("172.18.6.4", 8082);
        PrintWriter pw=new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
        pw.println("客户端请求");
        pw.flush();
        
        
        BufferedReader br=new BufferedReader(new InputStreamReader(socket.getInputStream()));
        String str=br.readLine();
        System.out.println(str);
    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package com.share.eg01_TCP;

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

public class TCPServer {
    public static void main(String[] args) {
        try {
            test();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    public static void test() throws IOException{
        ServerSocket server=new ServerSocket(8082);
        Socket socket=server.accept();
        
        BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        System.out.println(reader.readLine());;
        
        PrintWriter pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())));
        pw.println("对客户端的响应");
        pw.flush();
    }
}

实例6:

UDP实例

一方发送消息,一方接收消息

点对点的UDP,一方发送数据包,并限定了数据包内的内容和数据包需要到达的地方(ip和port端口)

另一方接收数据包,在socket上监听某一个端口接收数据并将接收的数据打包存进包里面

核心代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package com.share.eg02_UDP;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

public class UDPSend {
    public static void main(String[] args) {
        try {
            test();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    public static void test() throws Exception{
        String str="发送的消息";
        byte[] buf=str.getBytes();
        DatagramPacket packet=new DatagramPacket(buf,buf.length,InetAddress.getLocalHost(),8080);
        DatagramSocket socket=new DatagramSocket();
        socket.send(packet);
        System.out.println("发送成功");
    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package com.share.eg02_UDP;

import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class UDPReceive {
    public static void main(String[] args) {
        try {
            test();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    public static void test() throws Exception{
        DatagramSocket socket=new DatagramSocket(8080);
        byte[] buf=new byte[1024];
        DatagramPacket p=new DatagramPacket(buf, buf.length);
        socket.receive(p);
        System.out.println("接收成功");
        System.out.println(new String(p.getData(),0,p.getLength()));
    }
}

实例7:

聊天室(老师代码,太麻烦,自己不想写)

核心代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
package com.share.eg03_聊天室;

import java.awt.EventQueue;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Scanner;
import java.util.Vector;

public class ChatClient {

    public boolean loginflag = true;// 登录状态
    public ObjectOutputStream out = null;// 声明输出流对象
    public List<String> list = null;// 存储用户名
    public String name;// 登录的用户名
    Scanner input = null;//

    public ChatClient() {
        input = new Scanner(System.in);
        list = new ArrayList<String>();
    }

    public static void main(String[] args) {
        ChatClient cc = new ChatClient();
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    cc.creatClientSocket();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
        cc.start();

    }

    public void start() {
        System.out.println("欢迎来到xxx聊天室");
        login();
        while (true) {
            System.out.println("需要发送消息吗?     YES   NO.退出");
            String s = input.next();
            if ("yes".equalsIgnoreCase(s) || "y".equalsIgnoreCase(s)) {
                send();
            } else {
                exit();
            }
        }
    }

    public void creatClientSocket() {
        try {
            Socket socket = new Socket("172.18.6.4", 8082);// 创建一个Socket对象,并且指定IP地址及端口号
            out = new ObjectOutputStream(socket.getOutputStream());// 创建输出流对象
            new ClientThead(socket).start();// 启动线程
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public class ClientThead extends Thread {
        Socket socket = null;

        public ClientThead(Socket socket) {
            this.socket = socket;
        }
        @Override
        public void run() {
            BufferedReader br = null;
            try {
                br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                while (true) {
                    String info = br.readLine().trim();// 读取信息
                    if (!info.startsWith("MSG:")) {// 如果收到的信息不是消息
                        if (info.startsWith("退出:")) {
                            list.remove(info.substring(3));
                        } else {// 接收到的是登录用户
                            boolean bool = false;// 标记是否添加到用户列表中,true为不添加
                            bool = list.contains(info);
                            if (!bool) {
                                list.add(info);
                            }

                        }
                    } else {// 如果获得的是消息,则显示
                        DateFormat df = DateFormat.getDateInstance();// 获得DateFormat实例
                        String dateString = df.format(new Date()); // 格式化为日期
                        df = DateFormat.getTimeInstance(DateFormat.MEDIUM);// 获得DateFormat实例
                        String timeString = df.format(new Date()); // 格式化为时间
                        String sendUser = info.substring(4, info.indexOf(":发送给:"));// 获得发送信息的用户
                        String receiveInfo = info.substring(info.indexOf(":的信息是:") + 6);// 获得接收到的信息
                        System.out.println("  " + sendUser + "    " + dateString + "  " + timeString + "\n  "
                                + receiveInfo + "\n");
                    }
                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }
    }

    /**
     * 用户登录
     */
    public void login() {
        System.out.println("请输入用户名:");
        name = input.next();
        System.out.println("登陸成功");
        Vector<String> v = new Vector<String>();// 创建集合对象,用于存储发送的消息
        v.add("用户:" + name);// 添加登录用户
        try {
            out.writeObject(v);// 将用户向量发送到服务器
            out.flush();// 刷新输出缓冲区
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    /**
     * 退出程序
     */
    public void exit() {
        Vector<String> v = new Vector<String>();// 创建集合对象,用于存储发送的消息
        v.add("退出:" + name);// 添加登录用户
        try {
            out.writeObject(v);
            out.flush();// 刷新输出缓冲区
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        System.exit(0);// 正常退出
    }

    /**
     * 选择对应的用户进行聊天
     */
    public void chat() {

    }

    /**
     * 显示用户组
     */
    public void showClient() {

        for (int i = 0; i < list.size(); i++) {
            System.out.print(i + "、" + list.get(i) + "  ");
        }
        System.out.println();
    }

    /**
     * 发送消息
     */
    public void send() {
        if (list.size() == 0) {
            System.out.println("没有可以选择的聊天对象");
        } else {
            int n = -1;
            while (true) {
                System.out.println("请选择聊天对象:");
                showClient();
                n = input.nextInt();
                if (n >= 0 && n < list.size()) {
                    break;
                } else {
                    System.out.println("选择失败,重新选择");
                }
            }
            System.out.println("请输入要发送的消息:");
            String info = input.next();
            String msg = name + ":发送给:" + list.get(n) + ":的信息是: " + info;
            Vector<String> v = new Vector<String>();// 创建集合对象,用于存储发送的消息
            v.add(msg);// 将信息添加到集合中
            try {
                out.writeObject(v);
                out.flush();
            } catch (IOException e) {
                e.printStackTrace();
            }
            DateFormat df = DateFormat.getDateInstance();// 获得DateFormat实例
            String dateString = df.format(new Date()); // 格式化为日期
            df = DateFormat.getTimeInstance(DateFormat.MEDIUM);// 获得DateFormat实例
            String timeString = df.format(new Date()); // 格式化为时间
            System.out.println("  " + name + "    " + dateString + "  " + timeString + "\n  " + info + "\n");

        }
    }

}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
package com.share.eg03_聊天室;

import java.awt.BorderLayout;
import java.awt.Frame;
import java.awt.Image;
import java.awt.MenuItem;
import java.awt.PopupMenu;
import java.awt.SystemTray;
import java.awt.TrayIcon;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.URL;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Set;
import java.util.Vector;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

@SuppressWarnings("serial")
public class ChatServerFrame extends JFrame {
    private JTextArea ta_info;
    private ServerSocket server; // 声明ServerSocket对象
    private Socket socket; // 声明Socket对象socket
    private Hashtable<String, Socket> map = new Hashtable<String, Socket>();// 用于存储连接到服务器的用户和客户端套接字对象
    
    public void createSocket() {
        try {
            server = new ServerSocket(8082);// 创建服务器套接字对象
            while (true) {
                ta_info.append("等待新客户连接......\n");
                socket = server.accept();// 获得套接字对象
                ta_info.append("客户端连接成功。" + socket + "\n");
                new ServerThread(socket).start();// 创建并启动线程对象
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    class ServerThread extends Thread {
        Socket socket;
        public ServerThread(Socket socket) {
            this.socket = socket;
        }
        public void run() {
            try {
                ObjectInputStream ins = new ObjectInputStream(socket
                        .getInputStream());
                while (true) {
                    Vector v = null;
                    try {
                        v = (Vector) ins.readObject();
                    } catch (ClassNotFoundException e) {
                        e.printStackTrace();
                    }
                    if (v != null && v.size() > 0) {
                        for (int i = 0; i < v.size(); i++) {
                            String info = (String) v.get(i);// 读取信息
                            String key = "";
                            if (info.startsWith("用户:")) {// 添加登录用户到客户端列表
                                key = info.substring(3, info.length());// 获得用户名并作为键使用
                                map.put(key, socket);// 添加键值对
                                Set<String> set = map.keySet();// 获得集合中所有键的Set视图
                                Iterator<String> keyIt = set.iterator();// 获得所有键的迭代器
                                while (keyIt.hasNext()) {
                                    String receiveKey = keyIt.next();// 获得表示接收信息的键
                                    Socket s = map.get(receiveKey);// 获得与该键对应的套接字对象
                                    PrintWriter out = new PrintWriter(s
                                            .getOutputStream(), true);// 创建输出流对象
                                    Iterator<String> keyIt1 = set.iterator();// 获得所有键的迭代器
                                    while (keyIt1.hasNext()) {
                                        String receiveKey1 = keyIt1.next();// 获得键,用于向客户端添加用户列表
                                        out.println(receiveKey1);// 发送信息
                                        out.flush();// 刷新输出缓冲区
                                    }
                                }
                            } else if (info.startsWith("退出:")) {
                                key = info.substring(3);// 获得退出用户的键
                                map.remove(key);// 添加键值对
                                Set<String> set = map.keySet();// 获得集合中所有键的Set视图
                                Iterator<String> keyIt = set.iterator();// 获得所有键的迭代器
                                while (keyIt.hasNext()) {
                                    String receiveKey = keyIt.next();// 获得表示接收信息的键
                                    Socket s = map.get(receiveKey);// 获得与该键对应的套接字对象
                                    PrintWriter out = new PrintWriter(s
                                            .getOutputStream(), true);// 创建输出流对象
                                    out.println("退出:" + key);// 发送信息
                                    out.flush();// 刷新输出缓冲区
                                }
                            } else {// 转发接收的消息
                                key = info.substring(info.indexOf(":发送给:") + 5,
                                        info.indexOf(":的信息是:"));// 获得接收方的key值,即接收方的用户名
                                String sendUser = info.substring(0, info
                                        .indexOf(":发送给:"));// 获得发送方的key值,即发送方的用户名
                                Set<String> set = map.keySet();// 获得集合中所有键的Set视图
                                Iterator<String> keyIt = set.iterator();// 获得所有键的迭代器
                                while (keyIt.hasNext()) {
                                    String receiveKey = keyIt.next();// 获得表示接收信息的键
                                    if (key.equals(receiveKey) && !sendUser.equals(receiveKey)) {// 与接受用户相同,但不是发送用户
                                        Socket s = map.get(receiveKey);// 获得与该键对应的套接字对象
                                        PrintWriter out = new PrintWriter(s.getOutputStream(), true);// 创建输出流对象
                                        out.println("MSG:" + info);// 发送信息
                                        out.flush();// 刷新输出缓冲区
                                    }
                                }
                            }
                        }
                    }
                }
            } catch (IOException e) {
                ta_info.append(socket + "已经退出。\n");
            }
        }
    }
    
    public static void main(String args[]) {
        ChatServerFrame frame = new ChatServerFrame();
        frame.setVisible(true);
        frame.createSocket();
    }
    
    /**
     * Create the frame
     */
    public ChatServerFrame() {
        super();
        addWindowListener(new WindowAdapter() {
            public void windowIconified(final WindowEvent e) {
                setVisible(false);
            }
        });
        setTitle("聊天室服务器端");
        setBounds(100, 100, 385, 266);
        
        final JScrollPane scrollPane = new JScrollPane();
        getContentPane().add(scrollPane, BorderLayout.CENTER);
        
        ta_info = new JTextArea();
        scrollPane.setViewportView(ta_info);
        
        //托盘
        if (SystemTray.isSupported()){                                      // 判断是否支持系统托盘
            URL url=ChatServerFrame.class.getResource("server.png");          // 获取图片所在的URL
            ImageIcon icon = new ImageIcon(url);                            // 实例化图像对象
            Image image=icon.getImage();                                    // 获得Image对象
            TrayIcon trayIcon=new TrayIcon(image);                          // 创建托盘图标
            trayIcon.addMouseListener(new MouseAdapter(){                   // 为托盘添加鼠标适配器
                public void mouseClicked(MouseEvent e){                     // 鼠标事件
                    if (e.getClickCount()==2){                              // 判断是否双击了鼠标
                        showFrame();                                    // 调用方法显示窗体
                    }
                }
            });
            trayIcon.setToolTip("系统托盘");                                    // 添加工具提示文本
            PopupMenu popupMenu=new PopupMenu();                    // 创建弹出菜单
            MenuItem exit=new MenuItem("退出");                           // 创建菜单项
            exit.addActionListener(new ActionListener() {                   // 添加事件监听器
                public void actionPerformed(final ActionEvent arg0) {
                    System.exit(0);                                     // 退出系统
                }
            });
            popupMenu.add(exit);                                        // 为弹出菜单添加菜单项
            trayIcon.setPopupMenu(popupMenu);                           // 为托盘图标加弹出菜弹
            SystemTray systemTray=SystemTray.getSystemTray();           // 获得系统托盘对象
            try{
                systemTray.add(trayIcon);                               // 为系统托盘加托盘图标
            }catch(Exception e){
                e.printStackTrace();
            }
        }
    }
    public void showFrame(){
        this.setVisible(true);                                              // 显示窗体
        this.setState(Frame.NORMAL);
    }
}
 评论