3月20日——培训第84天

 真没想到今天又见到了讲linux的张老师……他好像要讲项目,田老师呢?怪死了,变来变去的,
其实也没关系,无论是这个张老师,还是田老师,我都没什么意见,当然或者是那个讲ajax的
王老师也是,都是可以的。

周二、周三、周四主要是说一下项目设计这一块,但是后面的时间安排并不是很清楚,CS和BS
两个、CS主要是图形界面的,BS是一个购物网站设计(邮件群发和搜索引擎两部分有点麻烦)

测试驱动的开发,测试代码编写……

今天实现局域网多人聊天的点对点的程序,功能不太强也无所谓,关键是要完整。

黑盒测试:功能测试(不需要知道源代码)
白盒测试:函数或是数据流测试(需要知道源代码)

性能测试:聊天软件能支持多少人同时在线,响应速度、CPU占用率、内存消耗等
压力测试:在极端条件下的性能测试。
回归测试:对修复后的做进一步测试
单元测试:验证某一个函数是否正常工作,函数之间调用是否正确
集成测试:各块代码集成在一起,实现一个或者一些功能,验证代码集成是否正确
系统测试:验证子系统之间的协调是否正确。
边界值测试:输入的边界值需要特别重视,还有边界值的左右两边的数值也是需要考虑的
等价类:
里程碑测试:软件项目众多阶段的其中之一(M1:第一阶段、M2:第二阶段、Beta:客户试用)
评审:对测试计划和测试用例的评审
Bug重现:发现问题后记录下这个问题,别人能够根据你的描述重新发现这个bug,如果不能够发现
  的话一般这种bug都不严重
BVT测试:版本升级结束后进行的测试
自动化测试:通过测试工具来实现的自动运行的测试。

--------------------------------------------------------------------------
需求分析、概要设计、详细设计、开发、测试、部署

需求分析:

聊天程序
操作系统:Windows2003 sp1、
数据库:oracle
开发工具:jbuilder2006
设计工具:powerdesigner12
开发周期:1人/月

功能模块:
一、聊天服务器模块
二、聊天客户端模块

子模块:
服务器模块:
1、注册模块
2、登录处理模块
3、监听客户机连接模块
4、消息处理模块(接收消息和发送消息)

客户机模块:
1、连接模块
2、注册模块
3、消息处理(接收消息和发送消息)
4、登录模块

需求目标:实现点对点发送和接收消息。采用C/S结构。使用swing技术开发

-----------------------------------------------------
概要设计:

监听客户机连接模块:
1、实现连续监听是否有客户机连接(多线程)
2、监听6000端口
3、有客户机连接:需要与客户机建立一个连接关系(socket编程或者rmi编程方式)


详细设计:

监听客户机连接模块:
功能实现:采用socket编程
1、API:采用的是java.net包中的api
java.net.Socket:用来连接到服务器
java.net.ServerSocket:用来建立服务器端的连接
消息传递:使用java.net.Socket中的getOutputStream(接收消息)和getInputStream(发送消息)

消息收发部分:
java.io.*:
java.io.PrintWriter:用来封装一个字节流……使用的构造方法要传入两个参数:
     PrintWriter(Writer out,boolean autoFlush)实现自动刷新内容
java.io.BufferedReader:封装字节流

端口监听部分:
ServerSocket(int port):在构造器中指定

地址处理:
java.net.InetAddress

--------------------------------------------------------------------------
用例图:
用例:功能模块
系统、角色、用例

系统:用长方形表示
角色:操作员(小人形状)
用例:椭圆形状图案


管理员、普通用户

功能用例1:监听端口(管理员)
功能用例2:管理注册(管理员)
功能用例3:聊天(普通用户)

--------------------------------------------
开发
1、图形界面:服务器端

frame默认的布局管理器叫做边界布局,borderlayout,特点是把整个屏幕分为
东南西北中五个部分,最多只能够放5个组件!如果不指出位置的话默认是居中显示,
而且是全屏,占满剩余空间

panel:默认的布局管理器是流布局,flowlayout,特点是逐行居中显示……

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

实现多线程有两种方法:继承线程类或是实现可运行接口

一般后者使用更多一些……

package chat ;

public class Test10 extends Thread
{
 public Test10(String name)
 {
  super(name);
 }

 private int i = 0 ;
 public void run()
 {
  while(true)
  {
   i = 0 ;
   //注意:观察结果的时候会发现两个线程是交互运行的!!
   if(i >= 500)
   {
    break ;
   }
   System.out.println(Thread.currentThread().getName()+"/t"+"i = "+i ++);
  }
 }

 public static void main(String[] args)
 {
  //通过构造器给线程赋予一个名字
  Test10 test = new Test10("第一个线程");
  Test10 test01 = new Test10("第二个线程") ;
  test01.start() ;
  test.start() ;
 }
};

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

如果要继承接口的话:

package chat ;

public class Test11 implements Runnable
{
 private int i = 0 ;

 public void run()
 {
  while(true)
  {
   i = 0 ;
   //注意:观察结果的时候会发现两个线程是交互运行的!!
   if(i >= 500)
   {
    break ;
   }
   System.out.println(Thread.currentThread().getName()+"/t"+"i = "+i ++);
  }
 }

 public static void main(String[] args)
 {
  Test11 test11 = new Test11() ;
  Thread t1 = new Thread(test11) ;
  Thread t2 = new Thread(test11) ;
  t1.start();
  t2.start();
 }
};

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

关于地址类处理的测试程序:
用到java.net.InetAddress

这个类本身没有构造器,但是以getLocalHost()为代表的静态方法可以取得类的实例。

package chat ;
import java.net.* ;

public class Test12
{
 //取得本机的主机名和ip地址
 public static void main(String[] args) throws Exception
 {
  Test12 test12 = new Test12() ;
  InetAddress add = InetAddress.getLocalHost() ;
  String hostName = add.getHostName() ;
  String ip = add.getHostAddress() ;
  System.out.println(hostName + "/t" + ip);
 
  //通过对方的名字来得到IP,如果没有DNS服务器的话……那得在windows的下列目录中更改:
  //C:/WINNT/system32/drivers/etc/hosts
  //更改hosts文件,在最后加上下面的类似的ip和对应的名称
  InetAddress add1 = InetAddress.getByName("www.abc.com");
  String ip1 = add1.getHostAddress() ;
  System.out.println(ip1);
 }
}


WINDOWS/system32/drivers/etc/hosts
 162.105.81.166  www.abc.com


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

Socket:

package chat ;

import java.net.* ;
import java.io.* ;

public class Test13
{
 public static void main(String[] args) throws Exception
 {
  Test13 test13 = new Test13() ;
  ServerSocket ss = new ServerSocket(5000) ;
  while(true)
  {
   Socket sk = ss.accept() ;  
   OutputStream os = sk.getOutputStream() ;
   PrintWriter out = new PrintWriter(os,true) ;//自动刷新
   out.println("成功连接到服务器!");
   
   //输出服务器端得到的信息
   //BufferedReader br =
   // new BufferedReader(new InputStreamReader(sk.getInputStream()));

   //String message = br.reakLine() ;
   //System.out.println(message) ;
   
   System.out.println(new String(sk.getInetAddress().getHostAddress()) + "已连接到服务器!");
  }
 }
}

telnet localhost 5000  就可以连接了……

再写一个客户端:

package chat ;

import java.net.* ;
import java.io.* ;

public class Test14
{
 public static void main(String[] args) throws Exception
 {
  Test14 test14 = new Test13() ;
  Socket ss =
   new Socket(InetAddress.getByName("www.rh1.com").getHostAddress(),5000) ;
  
  InputStream is = sk.getInputStream() ;
  BufferedReader br = new BufferedReader(new InputStreamReader(is)) ;//字节流包装成字符流
  String message = br.readLine() ;
  System.out.println(message);

  //PrintWriter out = new PrintWriter(sk.getOutputStream(),true) ;
  //out.print(new String(sk.getInetAddress().getAddress()) + "已经连接到服务器!!" );
  
 }
}

==========================================================================================

上面的代码有些乱,整理一下:

Socket服务器端代码:

package test;

 

import java.net.* ;
import java.io.* ;


public class TestSocket {
    public TestSocket() {
    }

    public static void main(String[] args) throws Exception
    {
       TestSocket test13 = new TestSocket() ;
       ServerSocket ss = new ServerSocket(5000) ;
       while(true)
       {
  Socket sk = ss.accept() ;  
  OutputStream os = sk.getOutputStream() ;
  PrintWriter out = new PrintWriter(os,true) ;//自动刷新
        out.println("成功连接到服务器!");
        System.out.println(new String(sk.getInetAddress().getHostAddress()) + "已连接到服务器!");
       }
    }

}


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

Socket服务器端代码:

package test;

import java.net.* ;
import java.io.* ;

public class SocketClient {
    public SocketClient() {
    }

    public static void main(String[] args) throws Exception{
        SocketClient socketclient = new SocketClient();
       
        Socket ss = new Socket(InetAddress.getByName("localhost").getHostAddress(),5000) ;
  //注意上面的getByName中的字符串也应该在hosts中进行响应的处理……
        InputStream is = ss.getInputStream() ;
        BufferedReader br = new BufferedReader(new InputStreamReader(is)) ;//字节流包装成字符流
        String message = br.readLine() ;
        System.out.println(message);      

    }
}


=====================================================================
启动服务器按钮:

使用内部类实现功能

 ServerSocket ss;
    Socket sk;
    int port = 5000;
    PrintWriter out;
    BufferedReader br;
   
    public class StartServer extends Thread {
        //ss = new Short()
        //int a = 100;
        //();
        public void run(){
            try {
                ss = new ServerSocket(port);
                while (true){
                    sk = ss.accept();
                    text.append("" + sk.getInetAddress().getHostAddress() + " 已连接到服务器!");
                    out = new PrintWriter(sk.getOutputStream(),true);
                    out.println("成功连接到服务器!");
                    br = new BufferedReader(new InputStreamReader(sk.getInputStream()));
                }
            }catch(Exception e){
                e.printStackTrace();
            }
           
        }
    }

//“启动服务器”按钮的代码
public void jButton1_actionPerformed(ActionEvent e)
{
 StartServer startServer = new StartServer() ;
 startServer.start() ;
}

这样先启动这个图形化界面,然后单击启动按钮,再启动刚才的客户端测试代码
就可以看到文本框中的提示信息了!!


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

下面改一下客户端程序:(注意:客户端的图形界面和服务器端的图形界面完全一样!)

点击“连接按钮”后,进行连接
import java.io.* ;
import java.net.* ;

Socket sk ;
int port = 5000 ;
PrintWriter out ;
BufferedReader br ;
String message1 = "" ;

public void jButton1_actionPerformed(ActionEvent e)
{
 String add = address.getText();
 try
 {
  sk = new Socket(add,port);
  br = new BufferedReader(new InputStreamReader(sk.getInputStream()));
  text.append(br.readLine()) ;
 }
 catch(Exception ee)
 {
  ee.printStackTrace() ;
 }
}

这样先启动服务器图形界面上的启动按钮,然后再单击客户端上面的连接按钮就可以看到效果了。
=========================================================================

下面来看看接收和发送消息:

接收是个服务器监听的过程,必须做成死循环

发送过程很简单……点击发送按钮就可以了……

//无论是服务器端还是客户端的发送按钮事件都这么写
public void jButton2_actionPerformed(ActionEvent e)
{
 out.print(message.getText());
 text.append(message.getText());
}


服务器端的多线程类还是定义成内部类:


BufferedReader br =
public class Rev extends Thread
{
 public void run()
 {
  try
  {
   String content = "" ;
   while(!content.equals("Exit!"))
   {
    if(br == null) return ;
    content = br.readLine() ;
    text.append(content + "/n")
   }
  }
  catch(Exception ee)
  {
   ee.printStackTrace() ;
  }
 }
}
===================================================================
===================================================================
===================================================================
下面的代码可能有一些问题在里面…………………………所以…………………………


老师写的代码:
服务器界面的Frame:


package chat;

import java.awt.BorderLayout;
import java.awt.Dimension;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.JTextPane;
import java.awt.Color;
import javax.swing.UIManager;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.*;
import java.io.*;

public class Frame5 extends JFrame {
    JPanel contentPane;
    BorderLayout borderLayout1 = new BorderLayout();
    JPanel jPanel1 = new JPanel();
    JPanel jPanel2 = new JPanel();
    JScrollPane jScrollPane1 = new JScrollPane();
    JTextArea text = new JTextArea();
    JButton jButton1 = new JButton();
    JTextPane jTextPane1 = new JTextPane();
    BorderLayout borderLayout2 = new BorderLayout();
    JPanel jPanel3 = new JPanel();
    JTextArea message = new JTextArea();
    JLabel jLabel1 = new JLabel();
    JButton jButton2 = new JButton();
    public Frame5() {
        try {
            setDefaultCloseOperation(EXIT_ON_CLOSE);
            jbInit();
        } catch (Exception exception) {
            exception.printStackTrace();
        }
    }

    /**
     * Component initialization.
     *
     * @throws java.lang.Exception
     */
    private void jbInit() throws Exception {
        contentPane = (JPanel) getContentPane();
        contentPane.setLayout(borderLayout1);
        this.setResizable(false);
        setSize(new Dimension(400, 300));
        setTitle("Frame Title");
        jButton1.setText("启动服务器");
        jButton1.addActionListener(new Frame5_jButton1_actionAdapter(this));
        jTextPane1.setText("jTextPane1");
        jPanel2.setLayout(borderLayout2);
        message.setRows(5);
        jLabel1.setText("输入要发送的消息:");
        jButton2.setText("发送");
        jButton2.addActionListener(new Frame5_jButton2_actionAdapter(this));
        text.setBackground(Color.cyan);
        contentPane.add(jPanel1, java.awt.BorderLayout.NORTH);
        jPanel1.add(jButton1);
        contentPane.add(jPanel2, java.awt.BorderLayout.SOUTH);
        contentPane.add(jScrollPane1, java.awt.BorderLayout.CENTER);
        jScrollPane1.getViewport().add(text);
        jPanel3.add(jLabel1);
        jPanel3.add(jButton2);
        jPanel2.add(jPanel3, java.awt.BorderLayout.CENTER);
        jPanel2.add(message, java.awt.BorderLayout.NORTH);
    }
   
    ServerSocket ss;
    Socket sk;
    int port = 5000;
    PrintWriter out;
    BufferedReader br = null;
   
    public class StartServer extends Thread {
        //ss = new Short()
        //int a = 100;
        //();
        public void run(){
            try {
                ss = new ServerSocket(port);
                while (true){
                    sk = ss.accept();
                    text.append("" + sk.getInetAddress().getHostAddress() + " 已连接到服务器!/n");
                    out = new PrintWriter(sk.getOutputStream(),true);
                    out.println("成功连接到服务器!/n");
                    br = new BufferedReader(new InputStreamReader(sk.getInputStream()));
                    if (br == null){
                        System.out.println("ssssssssssssssssssssssssssssssssssssss");
                    }
                    Rev rev = new Rev();
                    rev.start();
                }
            }catch(Exception e){
                e.printStackTrace();
            }
           
        }
    }
   
   
   
    public class Rev extends Thread {
        public void run(){
            try {
                String content = "";
             while (!content.equals("Exit!")){
                 if (br == null){
                     System.out.println("br is null");
                     return;
                 }
                  content = br.readLine();
                  System.out.println(content);
                 text.append(content + "/n");
             }
 
            }catch(Exception ee){
                ee.printStackTrace();
            }
           
        }
    }
   
    public void jButton1_actionPerformed(ActionEvent e) {
        StartServer startServer = new StartServer();
        startServer.start();
        //Rev rev = new Rev();
        //rev.start();
    }

    public void jButton2_actionPerformed(ActionEvent e) {
        out.print(message.getText());
        text.append(message.getText());
    }
}


class Frame5_jButton2_actionAdapter implements ActionListener {
    private Frame5 adaptee;
    Frame5_jButton2_actionAdapter(Frame5 adaptee) {
        this.adaptee = adaptee;
    }

    public void actionPerformed(ActionEvent e) {
        adaptee.jButton2_actionPerformed(e);
    }
}


class Frame5_jButton1_actionAdapter implements ActionListener {
    private Frame5 adaptee;
    Frame5_jButton1_actionAdapter(Frame5 adaptee) {
        this.adaptee = adaptee;
    }

    public void actionPerformed(ActionEvent e) {
        adaptee.jButton1_actionPerformed(e);
    }
}

 


客户端的Frame:

package chat;

import java.awt.BorderLayout;
import java.awt.Dimension;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.JButton;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import java.net.*;

public class Frame6 extends JFrame {
    JPanel contentPane;
    BorderLayout borderLayout1 = new BorderLayout();
    JPanel jPanel1 = new JPanel();
    JScrollPane jScrollPane1 = new JScrollPane();
    JLabel jLabel1 = new JLabel();
    JTextField address = new JTextField();
    JButton jButton1 = new JButton();
    JTextArea text = new JTextArea();
    JPanel jPanel2 = new JPanel();
    BorderLayout borderLayout2 = new BorderLayout();
    JPanel jPanel3 = new JPanel();
    JTextArea message = new JTextArea();
    JLabel jLabel2 = new JLabel();
    JButton jButton2 = new JButton();
    public Frame6() {
        try {
            setDefaultCloseOperation(EXIT_ON_CLOSE);
            jbInit();
        } catch (Exception exception) {
            exception.printStackTrace();
        }
    }

    /**
     * Component initialization.
     *
     * @throws java.lang.Exception
     */
    private void jbInit() throws Exception {
        contentPane = (JPanel) getContentPane();
        contentPane.setLayout(borderLayout1);
        setSize(new Dimension(400, 300));
        setTitle("Frame Title");
        jLabel1.setText("服务器IP地址:");
        address.setColumns(15);
        jButton1.setText("连接");
        jButton1.addActionListener(new Frame6_jButton1_actionAdapter(this));
        text.setBackground(Color.cyan);
        text.setEditable(false);
        jPanel2.setLayout(borderLayout2);
        message.setRows(5);
        jLabel2.setText("输入要发送的消息:");
        jButton2.setText("发送");
        jButton2.addActionListener(new Frame6_jButton2_actionAdapter(this));
        jPanel1.add(jLabel1);
        jPanel1.add(address);
        jPanel1.add(jButton1);
        contentPane.add(jScrollPane1, java.awt.BorderLayout.CENTER);
        jScrollPane1.getViewport().add(text);
        contentPane.add(jPanel1, java.awt.BorderLayout.NORTH);
        contentPane.add(jPanel2, java.awt.BorderLayout.SOUTH);
        jPanel2.add(jPanel3, java.awt.BorderLayout.SOUTH);
        jPanel3.add(jLabel2);
        jPanel3.add(jButton2);
        jPanel2.add(message, java.awt.BorderLayout.NORTH);
    }
    Socket sk;
    int port = 5000;
    PrintWriter out;
    BufferedReader br;
    String message1 = "";
   
    public void jButton1_actionPerformed(ActionEvent e) {
        String add = address.getText();
        try {
            sk = new Socket(add,port);
            br = new BufferedReader(new InputStreamReader(sk.getInputStream()));
            text.append(br.readLine());
            out = new PrintWriter(sk.getOutputStream(),true);
           Rev rev = new Rev();
            rev.start();
        }catch(Exception ee){
           
        }
       
    }
   
    public class Rev extends Thread {
       public void run(){
           try {
               String content = "";
            while (!content.equals("Exit!")){
                if (br == null){
                    System.out.println("br is null");
                    return;
                   
                }
        content = br.readLine();
        System.out.println(content);
                text.append(content + "/n");
            }

           }catch(Exception ee){
               ee.printStackTrace();
           }

       }
   }
  

    public void jButton2_actionPerformed(ActionEvent e) {
        out.print(message.getText());
        text.append(message.getText());
    }
}


class Frame6_jButton2_actionAdapter implements ActionListener {
    private Frame6 adaptee;
    Frame6_jButton2_actionAdapter(Frame6 adaptee) {
        this.adaptee = adaptee;
    }

    public void actionPerformed(ActionEvent e) {
        adaptee.jButton2_actionPerformed(e);
    }
}


class Frame6_jButton1_actionAdapter implements ActionListener {
    private Frame6 adaptee;
    Frame6_jButton1_actionAdapter(Frame6 adaptee) {
        this.adaptee = adaptee;
    }

    public void actionPerformed(ActionEvent e) {
        adaptee.jButton1_actionPerformed(e);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值