真没想到今天又见到了讲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);
}
}