java-se - 请教Java SWING Socket大神一个写清楚了全部实验源代码的IM通信实验中遇到的问题如何调试?
怪我咯
怪我咯 2017-04-18 10:25:44
0
0
497

高人,小弟在做一个IM通信系统的实验,现场如下:

小弟将通信构造为全双工通信,分为S端和C端。
package pack.Server; import java.awt.Dimension; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.ServerSocket; import java.net.Socket; import java.util.HashMap; import java.util.Vector; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JOptionPane; import javax.swing.JTextField; public class Server extends JFrame { /** * */ private static final long serialVersionUID = 1L; Vector v = new Vector(); // 创建存放客户端连接套接字的集合 int port;// 端口号 JTextField jtf; // 设置为属性 方便写事件的时候使用 public Server() { // 设置服务器默认窗口 this.setTitle("基于TCP协议的服务器中转聊天"); this.setSize(320, 100); Dimension d = Toolkit.getDefaultToolkit().getScreenSize(); this.setLocation(d.width / 2 - getWidth() / 2, d.height / 2 - getHeight() / 2); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setLayout(null); setAlwaysOnTop(true); // 文本框 输入端口号 jtf = new JTextField(); jtf.setColumns(10); jtf.setBounds(10, 10, 80, 30); jtf.addKeyListener(new KeyAdapter() { public void keyPressed(KeyEvent e) { char c = e.getKeyChar(); if ('\n' == c) { String s = jtf.getText(); if (s.matches("[0-9]{4,6}")) { port = new Integer(s); setVisible(false); // 该设置要放在服务区启动之前 } else { jtf.setText(""); JOptionPane.showMessageDialog(null, "请输入4-6位的数字!"); } } } }); this.add(jtf); // 按钮 启动服务器(事件) JButton jb = new JButton("启动服务器"); jb.setBounds(180, 10, 100, 30); jb.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { String s = jtf.getText(); if (s.matches("[0-9]{4,6}")) { port = new Integer(s); setVisible(false); // 该设置要放在服务区启动之前 begin(); // server(); } else { jtf.setText(""); JOptionPane.showMessageDialog(null, "请输入4-6位的数字!"); } } }); this.add(jb); this.setVisible(true); } public void begin() { // 创建服务器,并且不停等待客户端连接,并将客户端连接存入集合 try { ServerSocket s = new ServerSocket(port); System.out.println(" ===="+port); System.out.println("服务器已创建..."); while (true) { Socket c = s.accept();// 等待客户端响应 System.out.println("客户端+[" + c.getInetAddress() + "]已连接"); v.add(c); // 将连接的客户端套接字放入集合,存放起来 // 启动转发线程 Transmit t = new Transmit(c); // new一个线程实例 t.start(); } } catch (IOException e) { System.out.println("服务器启动出错"); } } public static void main(String[] args) { new Server().setVisible(true); } }

(上面是通信的S端点)

package pack.Client; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Font; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.OutputStreamWriter; import java.net.ServerSocket; import java.net.Socket; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.Map; import java.util.Set; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JPasswordField; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.JTextField; import javax.swing.SwingConstants; import javax.swing.border.TitledBorder; public class Client extends JFrame { String name; // 网名 String ip; // ip地址 int port; // 端口 Socket c;// 客户端套接字 JFrame jf1; // 客户端连接窗口 JTextField jtf1; // 网名 JTextField jtf2; // 输入IP的文本框 JTextField jtf3; // 输入端口的文本框 JFrame jf2;// 登陆界面窗口 JTextField jtf4; // 输入账号的文本框 JPasswordField jpf; // 输入密码的文本框 JLabel jl;// 登录窗口的提示信息 String user; String pwd; String pwd1; JFrame jf;// 聊天窗口 JTextField jtf; // 聊天窗口发送文字的文本框 JTextArea jta;// 聊天窗口的信息显示文本域 JFrame jf3;// 注册窗口 JTextField jtf6; // 注册账号的文本框 JPasswordField jtf7;// 输入注册密码的文本框 JPasswordField jtf8;// 确认密码 JLabel jl1; // 账号提示信息 JLabel jl2; // 密码提示信息 JLabel jl3;// 密码提示信息 static Map map = new HashMap();// 存放账号和密码 // private JLabel label_1; //密码提示jlable // 连接服务器的窗口 public Client() { // 默认设置 jf1 = this; // 把当前对象设置为jf1; this.setTitle("客户端连接窗口"); setSize(409, 139); Dimension d = Toolkit.getDefaultToolkit().getScreenSize();// 获取当前屏幕size this.setLocation(d.width / 2 - getWidth() / 2, d.height / 2 - getHeight() / 2); // 设置窗口位置居中 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setAlwaysOnTop(true); getContentPane().setLayout(null);// 布局方式为绝对布局 mouse m = new mouse(); // 新建一个鼠标事件类的实例 jtf1 = new JTextField(); // 用户名文本框 jtf1.setColumns(10); jtf1.setBounds(89, 10, 185, 30); jtf1.setText("admin"); // 默认用户 jtf1.addMouseListener(m); // 给该文本框添加鼠标事件 jf1.getContentPane().add(jtf1); jtf2 = new JTextField(); // ip文本框 jtf2.setColumns(10); jtf2.setBounds(48, 50, 100, 30); jtf2.setText("127.0.0.1"); // 默认IP jtf2.addMouseListener(m); // 点击清除文本内容事件 jf1.getContentPane().add(jtf2); jtf3 = new JTextField(); // port文本框 jtf3.setColumns(10); jtf3.setBounds(204, 50, 70, 30); jtf3.setText("8888"); // 默认端口 jtf3.addMouseListener(m); jf1.getContentPane().add(jtf3); JButton jb = new JButton("连接");// 连接按钮 jb.setFont(new Font("宋体", Font.BOLD, 18)); jb.setBounds(294, 28, 89, 52); jf1.getContentPane().add(jb); JLabel label = new JLabel("用户名:"); label.setFont(new Font("仿宋", Font.BOLD, 12)); label.setBounds(25, 17, 54, 15); jf1.getContentPane().add(label); JLabel lblIp = new JLabel("IP:"); lblIp.setFont(new Font("仿宋", Font.BOLD, 12)); lblIp.setBounds(25, 57, 54, 15); jf1.getContentPane().add(lblIp); JLabel lblPort = new JLabel("PORT:"); lblPort.setFont(new Font("仿宋", Font.BOLD, 12)); lblPort.setBounds(160, 57, 54, 15); jf1.getContentPane().add(lblPort); jb.addActionListener(new ActionListener() { // 点击“连接”触发事件 public void actionPerformed(ActionEvent e) { name = jtf1.getText(); String s = jtf2.getText(); String s1 = jtf3.getText(); if (s.matches( "\\b((?!\\d\\d\\d)\\d+|1\\d\\d|2[0-4]\\d|25[0-5])\\.((?!\\d\\d\\d)\\d+|1\\d\\d|2[0-4]\\d|25[0-5])\\." + "((?!\\d\\d\\d)\\d+|1\\d\\d|2[0-4]\\d|25[0-5])\\.((?!\\d\\d\\d)\\d+|1\\d\\d|2[0-4]\\d|25[0-5])\\b") && s1.matches("[0-9]{4,6}")) { ip = s; port = new Integer(s1); jf1.setVisible(false); // 原窗口隐藏 begin(); // 调用客户端启动方法 } else { JOptionPane.showMessageDialog(jf1, "请输入正确的地址或IP!"); jtf2.setText(""); jtf3.setText(""); } } }); } // 连接服务器的方法 public void begin() { try { System.out.println("ip===="+ip+" "+"port===="+port); c = new Socket(ip, port); System.out.println("客户端请求连接..."); new Recevie(c).start(); // 启接收信息的线程 // map.put("admin", "123456"); login(); // 登录窗口 } catch (IOException e) { JOptionPane.showMessageDialog(jf1, "请检查服务器是否开启,ip地址和端口是否正确..."); e.printStackTrace(); } } // 登录窗口 public void login() { // 导入用户信息 load(); // 声明 Dimension d; JLabel jl1, jl2; JButton jb1, jb2; // 创建设置窗口 jf2 = new JFrame(); jtf4 = new JTextField(); // 账号输入框 jl1 = new JLabel("账号"); // 设置控件 jf2.setTitle("登陆"); jf2.setSize(1300,1600); jf2.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); d = Toolkit.getDefaultToolkit().getScreenSize(); jf2.setLocation(d.width / 2 - jf2.getWidth() / 2, d.height / 2 - jf2.getHeight() / 2); jf2.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //jf2.getContentPane().setLayout(null); setAlwaysOnTop(true); getContentPane().setLayout( new FlowLayout());// 布局方式为绝对布局 jtf4.setBounds(86, 22, 198, 31); jtf4.setColumns(10); jl1.setFont(new Font("宋体", Font.BOLD, 16)); jl1.setBounds(30, 22, 54, 31); jpf = new JPasswordField(); // 登录界面 输入密码 jpf.setBounds(0, 0, 197, 31); jpf.setColumns(10); jl2 = new JLabel("密码"); jl2.setFont(new Font("宋体", Font.BOLD, 16)); jl2.setBounds(30, 90, 54, 15); jb1 = new JButton("注册"); jb1.setBounds(34, 171, 93, 23); jb2 = new JButton("登录"); jb2.setBounds(164, 171, 93, 23); jl = new JLabel(""); // 账号密码登录信息提示 jl.setBounds(48, 138, 236, 23); // jf2.getContentPane().setLayout(getLayout()); // 添加控件 jf2.getContentPane().add(jpf); // jf2.getContentPane().add(jl1); // // jf2.getContentPane().add(jtf4); // jf2.getContentPane().add(jl2); // jf2.getContentPane().add(jb1); // jf2.getContentPane().add(jb2); // jf2.getContentPane().add(jl); jf2.setVisible(true); // 添加事件 jtf4.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { jl.setText(""); // 账号提示信息 } }); jpf.addKeyListener(new KeyAdapter() { public void keyPressed(KeyEvent e) { if ('\n' == e.getKeyChar()) { // 按键事件 按回车键发送信息 Set set = map.keySet(); for (String string : set) { String u = string; String p = map.get(string); if (jtf4.getText().equals(u) && jpf.getText().equals(p)) { jf2.setVisible(false); LT(); } } jl.setText("账号或者密码错误!!"); jtf4.setText(""); jpf.setText(""); } } }); jb1.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) { jf2.setVisible(false); zhuce(); } }); jb2.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { Set set = map.keySet(); for (String string : set) { String u = string; String p = map.get(string); if (jtf4.getText().equals(u) && jpf.getText().equals(p)) { jf2.setVisible(false); LT(); } } jl.setText("账号或者密码错误!!"); jtf4.setText(""); jpf.setText(""); } }); //jf2.setVisible(true); ServerSocket ss = null; try { ss = new ServerSocket(9999); } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } while(true){ Socket s = null; try { s = ss.accept(); } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } Transmit obj = new Transmit(s); obj.start(); } } // 注册窗口 public void zhuce() { // 局部变量 JLabel jl11, jl22, jl33; JButton jb1; // 创建窗口、事件实例 jf3 = new JFrame(); key1 k1 = new key1(); mouse m = new mouse(); // 窗口默认设置 jf3.getContentPane().setFont(new Font("宋体", Font.PLAIN, 13)); jf3.setTitle("\u6CE8\u518C"); jf3.setSize(411, 287); Dimension d = Toolkit.getDefaultToolkit().getScreenSize(); jf3.setLocation(d.width / 2 - jf3.getWidth() / 2, d.height / 2 - jf3.getHeight() / 2); jf3.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); jf3.getContentPane().setLayout(null); // 基本控件的设置 jtf6 = new JTextField(); // 输入账号的文本框 jtf6.setBounds(109, 26, 226, 23); jtf6.setColumns(10); jtf7 = new JPasswordField(); // 第一次输入密码的文本框 jtf7.setColumns(10); jtf7.setBounds(109, 84, 226, 23); jtf8 = new JPasswordField(); // 第二次输入密码的文本框 jtf8.setColumns(10); jtf8.setBounds(109, 145, 226, 23); jl1 = new JLabel(""); jl1.setBounds(40, 59, 308, 15); jl2 = new JLabel(""); jl2.setBounds(27, 120, 308, 15); jl3 = new JLabel(""); jl3.setBounds(27, 178, 308, 15); jb1 = new JButton("提交"); // 注册信息确认按钮 jb1.setBounds(109, 203, 93, 23); jl11 = new JLabel("请输入账号"); jl11.setFont(new Font("宋体", Font.BOLD, 12)); jl11.setBounds(30, 26, 69, 23); jl22 = new JLabel("请输入密码"); jl22.setFont(new Font("宋体", Font.BOLD, 12)); jl22.setBounds(30, 84, 69, 23); jl33 = new JLabel("请再次密码"); jl33.setFont(new Font("宋体", Font.BOLD, 12)); jl33.setBounds(30, 145, 69, 23); // 面板添加控件 jf3.getContentPane().add(jl11); jf3.getContentPane().add(jl22); jf3.getContentPane().add(jl33); jf3.getContentPane().add(jb1); jf3.getContentPane().add(jl1); jf3.getContentPane().add(jl2); jf3.getContentPane().add(jl3); jf3.getContentPane().add(jtf6); jf3.getContentPane().add(jtf7); jf3.getContentPane().add(jtf8); // 添加事件 jtf6.addKeyListener(k1); jtf7.addKeyListener(k1); jtf8.addKeyListener(k1); jtf6.addMouseListener(m); jtf7.addMouseListener(m); jtf8.addMouseListener(m); jb1.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { user = jtf6.getText(); pwd = jtf7.getText(); pwd1 = jtf8.getText(); if (user.matches("^(?=.*?[a-zA-Z])(?=.*?[0-9])[a-zA-Z0-9]{6,}$")) { if (pwd.equals(pwd1)) { if (pwd.matches("^(?=.*?[a-zA-Z])(?=.*?[0-9])[a-zA-Z0-9]{6,}$")) { map.put(user, pwd); save(map); JOptionPane.showMessageDialog(jf3, "注册成功!"); jf3.setVisible(false); jf2.setVisible(true); } else { jl2.setText("(密码长度大于等于6且必须包含字符和数字)"); } } else { jl3.setText("(两次输入的密码必须一致)"); } } else { jl1.setText("(用户名长度大于等于6且必须包含字符和数字)"); } } }); jf3.setVisible(true); } // 聊天窗口 public void LT() { // 声明局部变量 Dimension d; JScrollPane jsp; JButton jb1, jb2, jb3; // 创建实例 key k = new key(); jf = new JFrame(); JPanel jp2 = new JPanel(); // 设置窗口 jf.setBackground(new Color(255, 255, 240)); jf.setTitle("基于TCP协议的聊天窗口---当前用户:" + name); jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); jf.setSize(400, 300); jf.setAlwaysOnTop(true); d = Toolkit.getDefaultToolkit().getScreenSize(); jf.setLocation(d.width / 2 - jf.getWidth() / 2, d.height / 2 - jf.getHeight() / 2); // 设置控件 jp2.setLayout(new BorderLayout(0, 0)); jta = new JTextArea(); // 聊天窗口 jta.setBackground(new Color(255, 255, 240)); jta.setFocusable(false);// 禁止鼠标光标进入 jsp = new JScrollPane(jta); // 设置滚屏 jsp.setBorder(new TitledBorder("聊天内容")); // 设置边框标题 jb1 = new JButton("抖动"); // 抖动按钮 jb1.setFont(new Font("微软雅黑", Font.BOLD, 12)); jtf = new JTextField(); // 发送文本框 jtf.setBackground(new Color(255, 255, 240)); jtf.setColumns(15); jb3 = new JButton("清空"); jb3.setFont(new Font("宋体", Font.BOLD, 12)); jb3.setHorizontalAlignment(SwingConstants.RIGHT); jb2 = new JButton("发送"); jb2.setFont(new Font("微软雅黑", Font.BOLD, 13)); // 添加控件 jp2.add(jb1, BorderLayout.WEST); jp2.add(jtf, BorderLayout.NORTH); jp2.add(jb3, BorderLayout.EAST); jf.getContentPane().add(jsp); jf.getContentPane().add(jp2, BorderLayout.SOUTH); jp2.add(jb2, BorderLayout.CENTER); // 添加事件 jtf.addKeyListener(k); jb1.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { BufferedWriter bw; try { bw = new BufferedWriter(new OutputStreamWriter(c.getOutputStream())); bw.write("dyd\n"); bw.flush(); } catch (IOException e2) { e2.printStackTrace(); } } }); jb2.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) { Send(); } }); jb3.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { jta.setText(""); } }); // 设置窗口可视化 jf.setVisible(true); } // 成员内部类-自定义鼠标事件-清空文本框内容 public class mouse extends MouseAdapter { public void mouseClicked(MouseEvent e) { JTextField j = (JTextField) e.getSource(); j.selectAll(); // 鼠标点击事件 点击清空文本框内容 } } // 成员内部类-自定义按键事件-回车发送信息 public class key extends KeyAdapter { public void keyPressed(KeyEvent e) { if ('\n' == e.getKeyChar()) { // 按键事件 按回车键发送信息 Send(); } } } // 成员内部类-自定义按键事件-回车确认注册信息 public class key1 extends KeyAdapter { public void keyPressed(KeyEvent e) { if ('\n' == e.getKeyChar()) { // 按键事件 按回车键发送信息 user = jtf6.getText(); pwd = jtf7.getText(); pwd1 = jtf8.getText(); if (user.matches("^(?=.*?[a-zA-Z])(?=.*?[0-9])[a-zA-Z0-9]{6,}$")) { if (pwd.equals(pwd1)) { if (pwd.matches("^(?=.*?[a-zA-Z])(?=.*?[0-9])[a-zA-Z0-9]{6,}$")) { map.put(user, pwd); save(map); JOptionPane.showMessageDialog(jf3, "注册成功!"); jf3.setVisible(false); jf2.setVisible(true); } else { jl2.setText("(密码长度大于等于6且必须包含字符和数字)"); } } else { jl3.setText("(两次输入的密码必须一致)"); } } else { jl1.setText("(用户名长度大于等于6且必须包含字符和数字)"); } } } } // 成员内部类-接收聊天信息的线程 public class Recevie extends Thread { Socket c; public Recevie(Socket c) { this.c = c; } public void run() { try { BufferedReader br = new BufferedReader(new InputStreamReader(c.getInputStream())); while (true) { String s = br.readLine(); if (s.equals("dyd")) { for (int i = 0; i < 100; i++) { if (i % 2 != 0) jf.setLocation(jf.getX() - 5, jf.getY() + 5); else jf.setLocation(jf.getX() + 5, jf.getY() - 5); } sleep(400); continue; } jta.append(s + "\n"); jta.setCaretPosition(jta.getDocument().getLength()); // 设置光标自动跟踪文本内容 } } catch (IOException e) { JOptionPane.showMessageDialog(jf, "服务器已关闭"); } catch (InterruptedException e) { e.printStackTrace(); } } } // 发送聊天信息的方法 public void Send() { try { BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(c.getOutputStream())); String time = new SimpleDateFormat("H:m:s").format(new Date().getTime()); String time1 = new SimpleDateFormat("yyyy-MM-dd").format(new Date().getTime()); bw.write(time1 + "\n" + time + " " + name + ":" + jtf.getText() + "\n"); bw.flush(); jtf.setText(""); } catch (IOException e) { e.printStackTrace(); } } // 保存用户信息的方法 public void save(Map map) { try { // System.out.println("测试保存"); ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("c:/save/user.txt")); oos.writeObject(map); oos.close(); } catch (IOException e) { e.printStackTrace(); } } // 读取信息的方法 public void load() { String paths=new File("a").getAbsolutePath(); System.out.println(paths+"\\user.txt"); ObjectInputStream ois; try { FileInputStream f= new FileInputStream("C:/Users/CJCO/Desktop/ws/cli/src/pack/Client/user.txt"); ois = new ObjectInputStream(f); Object o; o = ois.readObject(); map = (Map) o; ois.close(); } catch (FileNotFoundException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); }catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } //Object o = new Object(); } public static void main(String[] args) { new Client().setVisible(true); } }

(上述是C端源代码)

package pack.Client; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.Socket; import java.util.HashMap; public class Transmit extends Thread { // 实现转发功能的线程 Socket c; HashMap socketlib = new HashMap(); public Transmit(Socket c){ this.c= c; } public void run() { try { BufferedReader br = new BufferedReader(new InputStreamReader(c.getInputStream())); while (true) { // 循环读取 String s = br.readLine(); String[] str = s.split("丗"); String myuserId = str[0]; String myuserrole = str[1]; String myobjId = str[2]; String myobjrole = str[3]; String myInfo = str[4]; System.out.println(myuserId+" "+myuserrole+" "+myobjId+" "+myobjrole+" "+myInfo); socketlib.put(myuserId, this.c); WriteStr ws = new WriteStr(this.c,"CJCO丗C丗CJCO丗C"); ws.start(); } } catch (IOException e) { System.out.println(c.getInetAddress() + "已退出"); } } }

(上述为S端与C端内的Transmit类型的源代码)

package pack.Server; import java.io.BufferedWriter; import java.io.IOException; import java.io.OutputStreamWriter; import java.net.Socket; public class WriteStr extends Thread{ static Socket s = null; BufferedWriter bw = null; String str = null; public WriteStr(Socket s,String str){ this.s = s; try { bw = new BufferedWriter(new OutputStreamWriter(this.s.getOutputStream())); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } this.str=str; } public void run(){ try { bw.write("CJCO"+this.str); System.out.println("CJCO"+this.str); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }

(上述为在前边三个类型中所存在的WriteStr类型源代码)
高手,小弟用这几组源代码做实验,首先运行S端的Server类型,再运行C端的Client类型。得到的运行结果如下图:

求高手点拨:
小弟的代码,为什么会运行出一个“白屏窗口”?
小弟的代码,错在哪里?应当如何修改?
谢谢高手的过目!!

怪我咯
怪我咯

走同样的路,发现不同的人生

全員に返信 (0)
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!