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);
    }
}

發佈了111 篇原創文章 · 獲贊 6 · 訪問量 18萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章