前几日写的一篇简陋之极的java聊天室被各位前辈说是,一塌糊涂,乌烟瘴气,只是简单的实现了需要的功能,并未做到人性化。在下痛定思痛,心想还是先学会显示功能再做美化界面,美化代码的打算!
在奋斗了一天之后终于完成了集图片,文字,直线等功能为一体的群聊天室。先分析代码如下:
关于界面什么的我就不说了,笔者在前面的博客中有提过!直接附上各种功能的实现方法。
首先我们要传送信息,必须要让被传送的对象知道我们传送的是什么东西,所以在传送信息之前,我们首先要确定一个协议,比如说当客户端接收到的第一个int 值为1的时候,它接下来就要再接收4个int值,据此来画一条直线,而我服务器画一条直线的时候可以获得该直线的四个int值,但是在利用IO流发送这四个int值的时候,我首先要先发送一个1,也就是说我每次在要发送一天直线之前就要先发送一个1,当然在客户端读取的时候,我们第一次读取到的是1,就接收四个int。当读完四个int之后并画完一条直线之后我们还要读取数据,如果还是1的话,我们继续上面的操作,如果读取的是2,按照规定的协议,我们就调用相应的方法即可!!!!
现附上服务器发送直线的代码如下,该代码是写在界面类里面的内部类:
//鼠标进入事件 MouseListener ms=(new MouseListener(){ public void mousePressed(MouseEvent e){ x1=e.getX(); y1=e.getY(); } public void mouseReleased(MouseEvent e){ int x2=e.getX(); int y2=e.getY(); g.drawLine(x1,y1,x2,y2); ChatTools.castbyte(1); ChatTools.castbyte(x1); ChatTools.castbyte(y1); ChatTools.castbyte(x2); ChatTools.castbyte(y2); } public void mouseClicked(MouseEvent e){} public void mouseEntered(MouseEvent e){} public void mouseExited (MouseEvent e){} }); jp.addMouseListener(ms);
当然相应的我们也要在客户端定义一个读取数据的方法,首先我们要判断发送过来的是什么东西,我设置的协议是,如果首先读到的是1,接下来就画直线,如果读到的是2,接下来就接收一张图片,如果读到的是4,接下来读到的就是一段文字。该方法是放在客户端的线程中的,并且在线程的Run方法中调用该方法。
并且在每执行完一次操作之后,便再次读取一个int值,再次判断该int值为多少,以便得到下一个执行的指令。
public void processServer(Socket client){ try{ ins=client.getInputStream(); OutputStream out=client.getOutputStream(); dis = new DataInputStream(ins); dout=new DataOutputStream(out); int t=dis.readInt(); while(true){ //如果读到的是1,调用读取线段的方法 if(t==1){ readline(); } //读到的是2则调用接受画面的方法 if(t==2){ readPic(); } //如果读到的是4,则调用接受文字的方法 if(t==4){ readMsg(); } t=dis.readInt(); } }catch(Exception ef){ ef.printStackTrace(); } }
当判断int值为1的时候,我们就调用画直线的方法,该方法如下
//定义一个读取线段的方法 public void readline() { try { int x1=dis.readInt(); int y1=dis.readInt(); int x2=dis.readInt(); int y2=dis.readInt(); g.drawLine(x1,y1,x2,y2); } catch (IOException e) { e.printStackTrace(); } }
当然,我们需要在客户端和服务器都要定义相同功能的传送和接收方法。
现在我们再写一个文字的接收方法,首先我们会在文本输入框中输入字符,并获得该文本内容,每当按下发送这个按钮时便调用消息的传送方法,将该消息发送出去!
ActionListener al=(new ActionListener(){ public void actionPerformed(ActionEvent e){ String s=e.getActionCommand(); if(s.equals("创建")){ Chatserver cs=new Chatserver(9090,jta,dout,g); cs.start(); } //将服务器消息发给每个人 if(s.equals("发送")){ String msg=jte1.getText(); ChatTools.castMsg(msg); jta.append("服务器说:"+msg+"\r\n"); jte1.setText(""); }
其中ChatTools.castMsg();是一个消息群发的方法,该方法在队列类里面定义的,代码如下
//将一个消息发送给所有人 public static void castMsg(String str){ ChatTools.castbyte(4); for(int i=0;i<list.size();i++){ ServerThread st=list.get(i); st.sendMs(i+"说:"+str); } }
而sendMsg();则是一个消息的发送方法。该方法如下
//将发送消息的代码包装到一个方法中 public void sendMs(String msg){ try{ msg+="\r\n"; dout.write(msg.getBytes()); //强制输出 dout.flush(); }catch(Exception ef){} }
实现字符串传输的重中之重便是读取的方法,我们会首先获得一个为4的int值,然后我们就要调用字符串的读取方法
public void readMsg(){ try{ brd=new BufferedReader(new InputStreamReader(ins)); String input=brd.readLine(); jta.append(input +"\r\n"); }catch(Exception ef){} }
我使用的BufferedReader缓冲流,实现整行读取的方式,该方式不会产生乱码,所以还是不错的。
而我今天要重点讲的便是图片从文件中读取和传送的方法。
首先我们要获得图片,再者我们要获取图片的宽度和高度,在循环遍历每个像素点,获取该点的颜色值,接着我们便在画布中调用画线的方法,依次画出每个像素点,并相应的给每个点附上相应的颜色即可。这样一张图片就在自己的画布上显示出来了!代码如下
ActionListener al=(new ActionListener(){ public void actionPerformed(ActionEvent e){ String s=e.getActionCommand(); if(s.equals("创建")){ Chatserver cs=new Chatserver(9090,jta,dout,g); cs.start(); } //将服务器消息发给每个人 if(s.equals("发送")){ String msg=jte1.getText(); ChatTools.castMsg(msg); jta.append("服务器说:"+msg+"\r\n"); jte1.setText(""); } if(s.equals("图片")){ try { BufferedImage image = ImageIO.read(new File("2.jpg")); int m=image.getHeight(); int n=image.getWidth(); for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ rgb=image.getRGB(i,j); System.out.println(i); System.out.println(j); Color color=new Color(rgb); g.setColor(color); g.drawLine(i,j,i,j); ChatTools.castbyte(2); ChatTools.castbyte(rgb); ChatTools.castbyte(i); ChatTools.castbyte(j); } } } catch (IOException e1) { e1.printStackTrace(); }
能画出图片,当然我们就能发送图片,我们就能相应的读取图片,在发送图片信息的时候,我们每取出一个点,就能获得该店的颜色,我们就把该点横坐标和纵坐标以及颜色值发送过去。在接收端,我们会首先读到一个为2的int值,然后程序会调用图片的读取方法。方法如下
//图片的读取方法 public void readPic(){ int rgb; try { rgb = dis.readInt(); int i=dis.readInt(); int j=dis.readInt(); Color color =new Color(rgb); g.setColor(color); g.drawLine(i,j,i,j); } catch (IOException e) { e.printStackTrace(); } }
值此,我们就实现了图片的发送功能了。我的代码也差不多了,至于如果有什么需要改进的地方请各位多多指教,本人是新手,迫切渴望成长,我也知道我的代码可定有很多漏洞,望不吝赐教!!!!!!!!!!!
现在附上具体的代码:服务器的四个类
界面类
import java.awt.Color; import java.awt.Graphics; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.image.BufferedImage; import java.io.DataOutputStream; import java.io.File; import java.io.IOException; import javax.imageio.ImageIO; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JTextArea; import javax.swing.JTextField; public class MainServer { private int x1; private int y1; private Graphics g; private DataOutputStream dout; private int rgb; public void ShowUI(){ JFrame jf=new JFrame(); jf.setTitle(" 服务器"); jf.setSize(600,600); jf.setLayout(null); jf.setDefaultCloseOperation(3); JButton jb=new JButton("创建"); jb.setBounds(0,0,60,30); final JButton jm = new JButton("图片");// 实例化菜单栏的对象 jm.setBounds(70,0,60,30); jf.add(jm); JButton jb1=new JButton("发送"); jb1.setBounds(0,40,60,30); final JTextField jte1=new JTextField(30); jte1.setBounds(70,45,300,20); final JTextArea jta=new JTextArea(20,30); jta.setBounds(0,80,600,150); final JPanel jp=new JPanel(); jp.setBounds(0,250,600,600); jf.add(jb); jf.add(jb1); jf.add(jte1); jf.add(jta); jf.add(jp); jf.setVisible(true); jp.setBackground(Color.gray); this.g=jp.getGraphics(); ActionListener al=(new ActionListener(){ public void actionPerformed(ActionEvent e){ String s=e.getActionCommand(); if(s.equals("创建")){ Chatserver cs=new Chatserver(9090,jta,dout,g); cs.start(); } //将服务器消息发给每个人 if(s.equals("发送")){ String msg=jte1.getText(); ChatTools.castMsg(msg); jta.append("服务器说:"+msg+"\r\n"); jte1.setText(""); } if(s.equals("图片")){ try { BufferedImage image = ImageIO.read(new File("2.jpg")); int m=image.getHeight(); int n=image.getWidth(); for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ rgb=image.getRGB(i,j); System.out.println(i); System.out.println(j); Color color=new Color(rgb); g.setColor(color); g.drawLine(i,j,i,j); ChatTools.castbyte(2); ChatTools.castbyte(rgb); ChatTools.castbyte(i); ChatTools.castbyte(j); } } } catch (IOException e1) { e1.printStackTrace(); } } } }); jm.addActionListener(al); jb.addActionListener(al); jb1.addActionListener(al); //鼠标进入事件 MouseListener ms=(new MouseListener(){ public void mousePressed(MouseEvent e){ x1=e.getX(); y1=e.getY(); } public void mouseReleased(MouseEvent e){ int x2=e.getX(); int y2=e.getY(); g.drawLine(x1,y1,x2,y2); ChatTools.castbyte(1); ChatTools.castbyte(x1); ChatTools.castbyte(y1); ChatTools.castbyte(x2); ChatTools.castbyte(y2); } public void mouseClicked(MouseEvent e){} public void mouseEntered(MouseEvent e){} public void mouseExited (MouseEvent e){} }); jp.addMouseListener(ms); } public static void main(String[] args){ MainServer ms=new MainServer(); ms.ShowUI(); } }
处理客户机连接的两个线程类
import java.awt.Graphics; import java.io.DataOutputStream; import java.net.ServerSocket; import java.net.Socket; import javax.swing.JTextArea; public class Chatserver extends Thread{ private Graphics g; private int port; private JTextArea jta; private DataOutputStream dout;//输出流 private ServerSocket ss; public Chatserver(int port,JTextArea jta,DataOutputStream dout,Graphics g){ this.port=port; this.jta=jta; this.dout=dout; this.g=g; } public void run(){ setUpServer(port); } //在指定端口上创建一个服务器 public void setUpServer(int port){ try{ ss = new ServerSocket(port); System.out.println("服务器创建成功"); //等待客户机连接,并设置成循环等待状态 while(true){ Socket client=ss.accept(); System.out.println("欢迎进入我的服务器"); //启动一个线程去处理该对象 ServerThread st=new ServerThread(client,jta,dout,g); st.start(); ChatTools.add(st); ChatTools.castMsg("有人上线!!目前在线人数"+ChatTools.getsize()); } }catch(Exception ef){ ef.printStackTrace(); } } }
import java.awt.Color; import java.awt.Graphics; import java.io.BufferedReader; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.Socket; import javax.swing.JTextArea; public class ServerThread extends Thread{ private Socket client;//线程中处理的客户对象 private DataOutputStream dout;//输出流 private OutputStream out;//输出流 private DataInputStream dis;// private JTextArea jta; private BufferedReader brd; private InputStream ins; //创建线程对象时要传入他要处理的连接对象 private Graphics g; public ServerThread(Socket client,JTextArea jta,DataOutputStream dout,Graphics g){ this.client=client; this.jta=jta; this.dout=dout; this.g=g; } public void readMsg(){ try{ brd=new BufferedReader(new InputStreamReader(ins)); String input=brd.readLine(); jta.append("客户说:"+input +"\r\n"); ChatTools.castMsg(input); }catch(Exception ef){} } //将发送消息的代码包装到一个方法中 public void sendMs(String msg){ try{ msg+="\r\n"; dout.write(msg.getBytes()); //强制输出 dout.flush(); }catch(Exception ef){} } public void run(){ //在线程中 调用处理链接的方法 processChat(this.client); } //处理客户机进入的连接对象 public void processChat(Socket client){ try{ ins=client.getInputStream(); out=client.getOutputStream(); dis = new DataInputStream(ins); dout=new DataOutputStream(out); int t=dis.readInt(); while(true){ if(t==1){ readline(); } if(t==2){ readPic(); } if(t==4){ readMsg(); } t=dis.readInt(); } }catch(Exception ef){ ef.printStackTrace(); } } //发送int型值得方法 public void sendbyte(int x1){ try{ dout.writeInt(x1); dout.flush(); }catch(Exception e){} } //图片的读取方法 public void readPic(){ int rgb; try { rgb = dis.readInt(); int i=dis.readInt(); int j=dis.readInt(); Color color =new Color(rgb); g.setColor(color); g.drawLine(i,j,i,j); } catch (IOException e) { e.printStackTrace(); } } //定义一个读取线段的方法 public void readline() { try { int x1=dis.readInt(); int y1=dis.readInt(); int x2=dis.readInt(); int y2=dis.readInt(); g.drawLine(x1,y1,x2,y2); } catch (IOException e) { e.printStackTrace(); } } }
一个队列类,用来存储连接进服务器的客户机对象类
import java.util.ArrayList; import java.util.List; public class ChatTools { //保存处理线程的队列对象 static List<ServerThread> list=new ArrayList<ServerThread>(); private ChatTools(){ }//不需要创建引类对象,构造器则私有 //取得保存保存处理线程对象的队列 public static List<ServerThread> getAllthread(){ return list; } //将一个客户对应的处理线程对象加入到队列中 public static void add(ServerThread st){ //通知有人上线了 list.add(st); } public static int getsize(){ int i=list.size(); return i; } //将一个消息发送给所有人 public static void castMsg(String str){ ChatTools.castbyte(4); for(int i=0;i<list.size();i++){ ServerThread st=list.get(i); st.sendMs(i+"说:"+str); } } //定义一个字节群发的方法 public static void castbyte(int x1){ for(int i=0;i<list.size();i++){ ServerThread st=list.get(i); st.sendbyte(x1); } } }
接下来便是客户机的两个类
界面类
package 多人聊天室客户端; import java.awt.Color; import java.awt.Graphics; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.io.InputStream; import javax.imageio.ImageIO; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JTextArea; import javax.swing.JTextField; public class Mainchat { private MainchatThread mt; private Graphics g; private int x1; private int y1; private InputStream ins; private int rgb; public void ShowUI(){ JFrame jf=new JFrame(); jf.setTitle(" 客户机"); jf.setSize(600,500); jf.setLocation(700,0); jf.setLayout(null); jf.setDefaultCloseOperation(3); JButton jb=new JButton("连接"); jb.setBounds(0,0,60,30); final JButton jm = new JButton("图片");// 实例化菜单栏的对象 jm.setBounds(70,0,60,30); jf.add(jm); JButton jb1=new JButton("发送"); jb1.setBounds(0,40,60,30); final JTextField jte1=new JTextField(30); jte1.setBounds(70,45,300,20); final JTextArea jta=new JTextArea(20,30); jta.setBounds(0,80,600,150); JPanel jp=new JPanel(); jp.setBounds(0,250,600,400); jf.add(jb); jf.add(jb1); jf.add(jte1); jf.add(jta); jf.add(jp); jf.setVisible(true); jp.setBackground(Color.gray); this.g=jp.getGraphics(); ActionListener al=(new ActionListener(){ public void actionPerformed(ActionEvent e){ String s=e.getActionCommand(); if(s.equals("连接")){ try { mt=new MainchatThread("localhost",9090,jta,g,ins); if(mt.runing()){ mt.start(); } } catch (Exception e1) { e1.printStackTrace(); } } //将消息发给别人 if(s.equals("发送")){ String msg=jte1.getText(); jta.append("我说:"+msg+"\r\n"); MainchatThread.sendbyte(4); mt.sendMsg(msg); System.out.println("消息已经发送"); jte1.setText(""); } if(s.equals("图片")){ try { BufferedImage image = ImageIO.read(new File("2.jpg")); int m=image.getHeight(); int n=image.getWidth(); for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ rgb=image.getRGB(i,j); System.out.println(i); System.out.println(j); Color color=new Color(rgb); g.setColor(color); g.drawLine(i,j,i,j); MainchatThread.sendbyte(2); MainchatThread.sendbyte(rgb); MainchatThread.sendbyte(i); MainchatThread.sendbyte(j); } } } catch (IOException e1) { e1.printStackTrace(); } } } }); jm.addActionListener(al); jb.addActionListener(al); jb1.addActionListener(al); jf.setVisible(true); MouseListener ms=(new MouseListener(){ public void mousePressed(MouseEvent e){ x1=e.getX(); y1=e.getY(); System.out.println(x1); } public void mouseReleased(MouseEvent e){ int x2=e.getX(); int y2=e.getY(); g.drawLine(x1,y1,x2,y2); MainchatThread.sendbyte(1); MainchatThread.sendbyte(x1); MainchatThread.sendbyte(y1); MainchatThread.sendbyte(x2); MainchatThread.sendbyte(y2); } public void mouseClicked(MouseEvent e){} public void mouseEntered(MouseEvent e){} public void mouseExited (MouseEvent e){} }); jp.addMouseListener(ms); } public static void main(String[] args){ Mainchat ms=new Mainchat(); ms.ShowUI(); } }
线程类,用来运行客户机读取服务器发来的信息
package 多人聊天室客户端; import java.awt.Color; import java.awt.Graphics; import java.io.BufferedReader; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.Socket; import javax.swing.JTextArea; public class MainchatThread extends Thread{ private static DataOutputStream dout; private InputStream ins; private BufferedReader brd; private int port; private String ip; private JTextArea jta; private Graphics g; private DataInputStream dis; private Socket socket; public MainchatThread(String ip,int port,JTextArea jta,Graphics g,InputStream ins){ this.jta=jta; this.ip=ip; this.port=port; this.g=g; this.ins=ins; } public boolean runing(){ try{ socket=new Socket(this.ip,this.port); System.out.println("连接成功"); InputStream ins=socket.getInputStream(); OutputStream out=socket.getOutputStream(); dis=new DataInputStream(ins); dout=new DataOutputStream(out); return true; }catch (Exception e){ e.printStackTrace(); }return false; } //图片的读取方法 public void readPic(){ int rgb; try { rgb = dis.readInt(); int i=dis.readInt(); int j=dis.readInt(); Color color =new Color(rgb); g.setColor(color); g.drawLine(i,j,i,j); } catch (IOException e) { e.printStackTrace(); } } //发送信息 public void sendMsg(String msg){ try{ msg+="\r\n"; dout.write(msg.getBytes()); dout.flush(); }catch(Exception ef){} } public static void sendbyte(int i){ try{ dout.writeInt(i); dout.flush(); }catch(Exception ef){} } //读取服务端信息的方法 public void readMsg(){ try{ brd=new BufferedReader(new InputStreamReader(ins)); String input=brd.readLine(); jta.append(input +"\r\n"); }catch(Exception ef){} } public void readline(){ try{ int x1=dis.readInt(); int y1=dis.readInt(); int x2=dis.readInt(); int y2=dis.readInt(); g.drawLine(x1,y1,x2,y2); }catch(Exception ef){} } public void processServer(Socket client){ try{ ins=client.getInputStream(); OutputStream out=client.getOutputStream(); dis = new DataInputStream(ins); dout=new DataOutputStream(out); int t=dis.readInt(); while(true){ //如果读到的是1,调用读取线段的方法 if(t==1){ readline(); } //读到的是2则调用接收图片的方法 if(t==2){ readPic(); } //如果读到的是4,则调用接受文字的方法 if(t==4){ readMsg(); } t=dis.readInt(); } }catch(Exception ef){ ef.printStackTrace(); } } public void run(){ processServer(socket); } }
至此完结!!!
相关推荐
java聊天室 2个目标文件,简单。 java模拟掷骰子2个 1个目标文件,输出演示。 java凭图游戏 一个目标文件,简单。 java求一个整数的因子 如题。 Java生成密钥的实例 1个目标文件 摘要:Java源码,算法相关,密钥 ...
java聊天室 2个目标文件,简单。 java模拟掷骰子2个 1个目标文件,输出演示。 java凭图游戏 一个目标文件,简单。 java求一个整数的因子 如题。 Java生成密钥的实例 1个目标文件 摘要:Java源码,算法相关,...
java聊天室 2个目标文件,简单。 java模拟掷骰子2个 1个目标文件,输出演示。 java凭图游戏 一个目标文件,简单。 java求一个整数的因子 如题。 Java生成密钥的实例 1个目标文件 摘要:Java源码,算法相关,...
java聊天室 2个目标文件,简单。 java模拟掷骰子2个 1个目标文件,输出演示。 java凭图游戏 一个目标文件,简单。 java求一个整数的因子 如题。 Java生成密钥的实例 1个目标文件 摘要:Java源码,算法相关,...
java聊天室 2个目标文件,简单。 java模拟掷骰子2个 1个目标文件,输出演示。 java凭图游戏 一个目标文件,简单。 java求一个整数的因子 如题。 Java生成密钥的实例 1个目标文件 摘要:Java源码,算法相关,密钥 ...
java聊天室 2个目标文件,简单。 java模拟掷骰子2个 1个目标文件,输出演示。 java凭图游戏 一个目标文件,简单。 java求一个整数的因子 如题。 Java生成密钥的实例 1个目标文件 摘要:Java源码,算法相关,密钥 ...
将其解码,李四用张三的公钥加密信息,并发送给李四,张三用自己的私钥解密从李四处收到的信息…… Java利用DES私钥对称加密代码实例 同上 java聊天室 2个目标文件,简单。 java模拟掷骰子2个 1个目标文件,输出演示...
将其解码,李四用张三的公钥加密信息,并发送给李四,张三用自己的私钥解密从李四处收到的信息…… Java利用DES私钥对称加密代码实例 同上 java聊天室 2个目标文件,简单。 java模拟掷骰子2个 1个目标文件,输出演示...
195 第6章 Java C/S结构编程 197 实例67 实现C/S多线程 198 实例68 客户端程序 200 实例69 服务器端程序 201 实例70 C/S结构聊天室 203 实例71 基于C/S的小游戏 209 实例72 应用C/S数据库 237...
实例200 简单的JSP多人聊天室 653 实例201 Servlet生成的动态图片 658 实例202 简单的JSP上传文件 661 实例203 用Servlet获取Web服务器信息 666 实例204 可选择的图形验证码 670 实例205 简单的页面注册 675 ...
实例64 实现SQL语句的检索功能 192 实例65 SQL嵌套检索 194 实例66 获取数据库基本信息 195 第6章 Java C/S结构编程 197 实例67 实现C/S多线程 198 实例68 客户端程序 200 实例69 服务器端程序 201 实例70 C/S结构...
可以在局域网中实现文字及大图片的传输。 可以实现局域网视频。 可以实现多用户的信息通信。 系统运行稳定、安全可靠。 操作注意事项 (1)在一台计算机中,不可以登录两个或两个以上的用户。 (2)在...
第1篇 基础篇 第1章 开发环境搭建 2 1.1 JDK开发工具包 3 1.2 Tomcat服务器 8 1.3 Linux系统配置JDK与Tomcat服务器 16 第2章 Java语言基础 20 2.1 基本语法 21 ...23.5 聊天室 885 23.6 万年历 901
第1篇 基础篇 第1章 开发环境搭建 2 1.1 JDK开发工具包 3 1.2 Tomcat服务器 8 1.3 Linux系统配置JDK与Tomcat服务器 16 第2章 Java语言基础 20 2.1 基本语法 21 ...23.5 聊天室 885 23.6 万年历 901
学生园地展示学生作品,学校留言本,聊天室,学校论坛,可给教师,学生,家长一个沟通的平台等学校教学教育科研,教研事业单位性质的网站,做适合新时代的电子教学,网络学校,网络教学,信息化学校网站管理系统. 完美的ASP编程...