Java网络编程实践报告 本文关键词:网络编程,实践,报告,Java
Java网络编程实践报告 本文简介:Java网络编程实践(基于C/S的控制台聊天室)课程设计说明书课程名称:Java网络课程实践题目:基于C/S的控制台聊天室姓名:董丽蓉学号:200905143教学班号:01指导教师:王小刚兰州交通大学软件科学与工程系二○一一*年*月*日任务书:题目3:基于C/S的控制台聊天室(1人)实现几个客户端的
Java网络编程实践报告 本文内容:
Java网络编程实践(基于C/S的控制台聊天室
)
课程设计说明书
课程名称:Java网络课程实践
题目:基于C/S的控制台聊天室
姓名:董丽蓉
学号:200905143
教学班号:01
指导教师:王小刚
兰州交通大学软件科学与工程系
二○一一*年*月*日
任务书:
题目
3:基于C/S的控制台聊天室(1人)
实现几个客户端的群聊(在控制台窗口显示聊天信息),信息经服务端转发和群发,多客户端使用多线程。基于Socket。注意:在每一个客户端窗口要显示所有参与聊天者的聊天内容,包括谁发言及发言内容。
文档内容要求:
1、在做上述题目时,正文要求包含4部分内容:1)项目简述和目的
2)解题基本思路;3)分析和设计
2、文档装订顺序:1)封面;2)任务书;3)团队成员及分工列表;3)正文。
3、打印格式要求:
?
纸型:B5
?
页边距:上2.54cm;下2.54cm;左2.2cm;右1.9cm;装订线为0
?
字体、格式要求:
题目:2号黑体不加粗,居中,段前段后间距1行。子标题字体为4号黑体。所有的子标题均加粗,置于页面最左端,段前段后间距均设为0.5行。文章正文皆为5号宋体,行距为固定值22磅,字距为标准。图、表的标题文字采用小5号黑体,表中的文字采用小5号宋体
基于C/S的控制台聊天室
一、
设计目的
巩固所学的Java语言基础知识,增进Java语言的编辑基本功,拓展常用类库的应用,使我们通过教学环节与手段,把所学的课程及相关知识加以融会贯通,
二、设计内容
运用Java程序编写聊天室,实现简单的聊天功能。它是图形界面,线程,流与文件系统等技术的综合应用。其界面主要采用了Java.awt包,Java.swing包等。程序实现了聊天室的基本功能,其中有:
1.
启动服务器。
2.
启动登录界面。
3.
进入客户端界面。
4.
发送信息。
5.
离开客户端界面。
6.
关闭服务器。
三、
分析
1.首先通过继承JFrame类构造服务器界面。使服务器能够为每一个客户启动一个线程,记录客户的上下线行为、登录的IP,发送消息的时刻,监视客户的聊天记录,对于出现不文明的话语,在客户端进行屏蔽,并统计出现不文明用语的次数,超过三次提示警告信息,并将其踢出聊天室。
2.设计客户端程序使其能够完成正常的通信功能,并且可以更改背景颜色,设置字体颜色。
3.设计登录程序,使其显示登录的IP地址端口号,以及用户昵称,通过登录按钮可以调用客户端程序,实现;聊天功能。
四、详细设计
程序中引入的包:
import
java.net.*;
import
java.io.*;
import
java.util.*;
import
java.awt.event.*;
import
java.awt.*;
import
java.javax.swing.*;
1)
服务器端代码中用户自定义的类:
类名:Server
作用:服务器的启动
继承的类:JFrame,构造服务器界面。
定义的对象:
TextArea
文本域
Java.awt.List
在线客户列表
SeverSocket
服务器
Socket
客户端
主要成员方法:
void
init()
构造服务器端的界面
public
void
actionPerformed(ActionEvent
e)
按钮监听器
public
void
keyPressed(KeyEvent
e)
键盘监听器
类名:start
作用:启动服务器的线程
继承的类名:thread
主要的成员方法:
Public
void
run()
启动服务器的线程
类名:SgService
继承的类名:thread
主要的成员方法:
public
void
run()
处理单个客户的线程
2)
用户登录相关的类:
类名:login
作用:构造登录界面
继承的类:JFrame
实现的接口:ActionListener
构造方法:public
login()
主要的成员方法:public
void
actionPerformed(ActionEvent
e)
实现登录和取消按钮的监听器
类名:loginStart
继承的类:thread
主要的方法:public
void
run()
作用:如果登录成功,则弹出客户端聊天窗口,如果登录失败,则打印出登录失败,以告知客户
3)
客户端相关的类:
类名:Client
继承的类:JFrame
实现的接口:ActionListener
构造方法:public
Client(PrintStream
out,BufferedReader
in,String
name)
主要的成员方法:public
void
receive()
接受服务端发来的信息
五.主要程序源代码
//聊天室服务器
import
java.net.*;
import
java.io.*;
import
java.util.*;
import
java.awt.event.*;
import
java.awt.*;
import
javax.swing.*;
class
Server
extends
JFrame{
private
TextArea
msgA=new
TextArea();
//服务器用来输入用的文本域
private
TextArea
area=new
TextArea();
//服务器显示消息的文本域
private
TextField
portT=new
TextField(“8888“);
private
java.awt.List
list=new
java.awt.List();
//在线客户列表
private
ServerSocket
server;//服务器
private
Socket
client;
//客户端
private
Map
container=new
HashMap();
//HashMap
void
init(){
Panel
p1=new
Panel();
Panel
p2=new
Panel();
Panel
p3=new
Panel();
Panel
p4=new
Panel();
Panel
p5=new
Panel();
Panel
p6=new
Panel();
Panel
p7=new
Panel();
Panel
p8=new
Panel();
Panel
p9=new
Panel();
Panel
p10=new
Panel();
//设置两个重要的文本框
Label
lb1=new
Label(“服务器界面“);
lb1.setBackground(new
Color(250,120,150));
Label
lb2=new
Label(“port“);
BorderLayout
border1=new
BorderLayout();
p1.setLayout(border1);
p1.add(BorderLayout.CENTER,area);
BorderLayout
border2=new
BorderLayout();
p5.setLayout(border2);
p5.add(BorderLayout.NORTH,p3);
p5.add(BorderLayout.CENTER,msgA);
BorderLayout
border3=new
BorderLayout();
p7.setLayout(border3);
p7.add(BorderLayout.CENTER,p1);
p7.add(BorderLayout.SOUTH,p5);
p7.setBackground(new
Color(250,150,200));
JButton
startButton=new
JButton(“启动服务“);
JButton
sendButton=new
JButton(“发送“);
JButton
flushButton=new
JButton(“刷新列表“);
FlowLayout
f1=new
FlowLayout(FlowLayout.LEFT);
p8.setLayout(f1);
p8.add(lb2);
p8.add(portT);
p8.add(startButton);
p8.add(sendButton);
p8.add(flushButton);
p8.setBackground(new
Color(250,120,150));
BorderLayout
border4=new
BorderLayout();
p9.setLayout(border4);
p9.add(BorderLayout.CENTER,p7);
p9.add(BorderLayout.SOUTH,p8);
p10.setLayout(new
BorderLayout());
Label
lb3=new
Label(“在线用户“);
lb3.setBackground(new
Color(250,120,150));
p10.add(lb3,BorderLayout.NORTH);
p10.add(list,BorderLayout.CENTER);
area.setEditable(false);
BorderLayout
border=new
BorderLayout();
this.addWindowListener(new
WindowAdapter(){
public
void
windowClosing(WindowEvent
arg0){
System.exit(0);
}
});
this.setLayout(border);
this.add(BorderLayout.NORTH,lb1);
this.add(BorderLayout.CENTER,p9);
this.setTitle(“聊天服务器“);
this.setBounds(100,100,600,550);
this.setVisible(true);
//“启动服务”按钮监听器
startButton.addActionListener(new
ActionListener(){
public
void
actionPerformed(ActionEvent
e){
Thread
t=new
Start();
t.start();
}
});//启动服务按钮监听器
//发送按钮监听器
sendButton.addActionListener(new
ActionListener(){
public
void
actionPerformed(ActionEvent
e){
String
msg
=msgA.getText();
if(msg!=null
int
hh=ca.get(Calendar.HOUR_OF_DAY);
int
mm=ca.get(Calendar.MINUTE);
int
ss=ca.get(Calendar.SECOND);
String
time=new
String(hh+“:“+mm+“:“+ss+““);
broadcast(time
+“[系统消息]:“+msg);
//那么广播这条消息
area.append(time+“[系统消息]:“+msg+“/n“);
msgA.setText(““);
}
}
});//end
//刷新按钮监听器
flushButton.addActionListener(new
ActionListener(){
public
void
actionPerformed(ActionEvent
e){
if(list!=null){
list.removeAll();
//清空在线用户列表,以便刷新
}
Set>
mySet=container.entrySet();
for(Iterator>
it=mySet.iterator();it.hasNext();){//刷新列表
Map.Entry
me=it.next();
String
aClientName=me.getKey();
Socket
aClient=me.getValue();
String
aClientAddress=aClient.getInetAddress().getHostAddress();
list.add(aClientName+“---“+aClientAddress);
}
}
});
msgA.addKeyListener(new
KeyAdapter(){//从键盘监听器---按下Enter发送消息
public
void
keyPressed(KeyEvent
e){
int
value=e.getKeyCode();
if(value==KeyEvent.VK_ENTER){
String
msg=msgA.getText();
Calendar
ca=new
GregorianCalendar();
int
hh=ca.get(Calendar.HOUR_OF_DAY);
int
mm=ca.get(Calendar.MINUTE);
int
ss=ca.get(Calendar.SECOND);
String
time=new
String(hh+“:“+mm+“:“+ss+““);
broadcast(time
+“[系统消息]:“+msg);
//那么广播这条消息
area.append(time+“[系统消息]:“+msg+“/n“);
msgA.setText(““);
}
}
});
}
class
Start
extends
Thread
//启动服务器的线程
{
public
void
run(){
try{
if(server!=null
}
else{
server=new
ServerSocket(Integer.parseInt(portT.getText()));//启动服务器
area.append((new
Date()).toString()+“/n“+“[恭喜!(*^__^*)
嘻嘻……]“+“服务器启动成功!“+“/n/n“);
}
while(true){
client=server.accept();
Thread
sgS=new
SgService(client);
//为每位登录的客户创建一个线程
sgS.start();
//启动客户线程
}
}
catch(Exception
e){
System.out.println(“cuowu
1“);
e.printStackTrace();
}
}
}
//处理单个客户的线程
class
SgService
extends
Thread
{
private
Socket
client=null;//客户套接字
private
BufferedReader
br=null;//输入流
private
PrintStream
ps=null;
private
int
counter=0;//记录是第几次接受用户的信息
private
int
mark=0;//记录用户说不文明用语的次数
private
String
name=null;
SgService(Socket
client){//构造方法
this.client=client;
}
public
void
run(){//run---begin
try{
br=new
BufferedReader(new
InputStreamReader(client.getInputStream()));
ps=new
PrintStream(client.getOutputStream());
String
msg=null;
while((msg=br.readLine())!=null){//无限循环意味着可以和用户进行无限次交互
if(counter==0){
name=
msg;
container.put(name,client);
list.add(name+“---“+client.getInetAddress().getHostAddress());
Calendar
ca=new
GregorianCalendar();
int
hh=ca.get(Calendar.HOUR_OF_DAY);
int
mm=ca.get(Calendar.SECOND);
String
time=hh+“:“+mm+“:“+““;
broadcast(time+name+“上线了!/n/n“);
counter++;
}
else{
if(msg.equals(“你是个笨蛋“)){
mark=mark+1;
if(mark>
mySet=container.entrySet();
Iterator>
it=mySet.iterator();
String
message=msg;
while(it.hasNext()){//如果列表中还有客户
Map.Entry
me=it.next();
Socket
tempClient=me.getValue();
singleCom(message,tempClient);//就把消息发给这个客户
}
}
//向单个客户发送消息
private
void
singleCom(String
msg,Socket
aClient){//singleCommunition---begin
try{
PrintStream
pw=new
PrintStream(aClient.getOutputStream());
String
message=msg;
pw.println(msg);
}catch(Exception
ex){
ex.printStackTrace();
}
}
public
static
void
main(String[]
args){
new
Server().init();//启动服务器窗口
System.out.println(“服务器“);
}
}
//聊天室客户端
import
java.awt.event.*;
import
javax.swing.*;
import
java.io.*;
import
java.net.*;
import
java.awt.*;
class
Client
extends
JFrame
{
PrintStream
out;//输出流
BufferedReader
in;//输入流
String
name;
TextArea
area=new
TextArea();
TextArea
msgA=new
TextArea();
TextField
frdNameT=new
TextField(10);
List
list=new
List();
Panel
p10=new
Panel();
JButton
sendButton=new
JButton(“发送“);
JButton
closeButton=new
JButton(“关闭“);
JButton
jb1=new
JButton(“设置字体颜色“);
JButton
jb2=new
JButton(“设置背景颜色“);
Label
lb1=new
Label(“昵称“);
void
init(){
this.pack();
//设置几个面板
Panel
p1=new
Panel();
Panel
p2=new
Panel();
Panel
p3=new
Panel();
Panel
p4=new
Panel();
Panel
p5=new
Panel();
Panel
p6=new
Panel();
Panel
p7=new
Panel();
Panel
p8=new
Panel();
Panel
p9=new
Panel();
lb1.setBackground(Color.pink);
//设置两个主要的文本框
BorderLayout
border1=new
BorderLayout();
p1.setLayout(border1);
p1.add(BorderLayout.CENTER,area);
area.setEditable(false);
FlowLayout
f2=new
FlowLayout(FlowLayout.LEFT);
p3.setLayout(f2);
p3.add(jb1);
p3.add(jb2);
BorderLayout
border2=new
BorderLayout();
p5.setLayout(border2);
p5.add(BorderLayout.NORTH,p3);
p5.add(BorderLayout.CENTER,msgA);
p5.setBackground(Color.pink);
BorderLayout
broder3=new
BorderLayout();
p7.setLayout(broder3);
p7.add(BorderLayout.CENTER,p1);
p7.add(BorderLayout.SOUTH,p5);
FlowLayout
f1=new
FlowLayout(FlowLayout.RIGHT);
p8.setLayout(f1);
p8.add(sendButton);
p8.add(closeButton);
p8.setBackground(Color.pink);
BorderLayout
broder4=new
BorderLayout();
p9.setLayout(broder4);
p9.add(BorderLayout.CENTER,p7);
p9.add(BorderLayout.SOUTH,p8);
//窗口关闭
this.addWindowListener(new
WindowAdapter(){
public
void
windowClosing(WindowEvent
arg0){
System.exit(0);
}
});
BorderLayout
broder5=new
BorderLayout();
p10.setLayout(broder5);
p10.add(BorderLayout.CENTER,list);
p10.setBackground(Color.blue);
//添加字体颜色的监听器
jb1.addActionListener(new
ActionListener(){
public
void
actionPerformed(ActionEvent
e){
JColorChooser
chooser4=new
JColorChooser();
Color
color=chooser4.showDialog(Client.this,“我的调色盘“,Color.yellow);
area.setForeground(color);
msgA.setForeground(color);
list.setForeground(color);
}
});
jb2.addActionListener(new
ActionListener(){
public
void
actionPerformed(ActionEvent
e){
JColorChooser
chooser4=new
JColorChooser();
Color
color=chooser4.showDialog(Client.this,“我的调色盘“,Color.yellow);
area.setBackground(color);
}
});
BorderLayout
border=new
BorderLayout();
this.setLayout(border);
this.add(BorderLayout.NORTH,lb1);
this.add(BorderLayout.CENTER,p9);
this.add(BorderLayout.EAST,p10);
this.setTitle(“聊天室客户端“);
this.setSize(700,600);
this.setVisible(true);
sendButton.addActionListener(new
ActionListener(){//“发送”按钮监听器
public
void
actionPerformed(ActionEvent
e){
String
msg
=msgA.getText();
msgA.setText(““);//清空输入文本域
out.println(msg);
}
});
msgA.addKeyListener(new
KeyAdapter(){//键盘监听器---按下enter发送信息
public
void
keyPressed(KeyEvent
e){
int
value=e.getKeyCode();
if(value==KeyEvent.VK_ENTER){
String
msg=msgA.getText();
msgA.setText(““);//清空文本域
out.println(msg);
}
}
});
closeButton.addActionListener(new
ActionListener(){//关闭监听器
public
void
actionPerformed(ActionEvent
e){
System.exit(100);
}
});
}
public
Client(PrintStream
out,BufferedReader
in,String
name){//构造方法
this.out=out;
this.in=in;
this.name=name;
lb1.setText(“昵称:“+name);
init();//弹出客户端窗口
out.println(name);
receive();//开始与服务器通信
}
public
void
receive(){//接收服务器端发来的信息
try{
String
text=null;
while((text=in.readLine())!=null){
this.area.append(text+“/n“);//在area上读入的内容
}
}
catch(IOException
e){
e.printStackTrace();//TODO
Auto-generated
catch
block
}
finally{
try
{
in.close();
out.close();
}
catch(Exception
ex)
{
ex.printStackTrace();
}
}
}
}
//登录界面
import
javax.swing.*;
import
java.awt.*;
import
java.awt.event.*;
import
java.io.*;
import
java.net.*;
class
login
extends
JFrame
implements
ActionListener
{
TextField
txtPort;
TextField
txtIP;
TextField
txtName;
JButton
btnLogin;
JButton
btnCancel;
Socket
toServer;
BufferedReader
in;
PrintStream
out;
public
login(){
Panel
p1=new
Panel();
Panel
p2=new
Panel();
Panel
p3=new
Panel();
Panel
p4=new
Panel();
Panel
p5=new
Panel();
Label
l1=new
Label(“port“);
Label
l2=new
Label(“IP“);
Label
l3=new
Label(“昵称“);
txtPort=new
TextField(“8888“,15);
txtIP=new
TextField(“127.0.0.1“,15);
txtName=new
TextField(“小敏“,15);
p2.add(l1);
p2.add(txtPort);
p3.add(l2);
p3.add(txtIP);
p4.add(l3);
p4.add(txtName);
GridLayout
g=new
GridLayout(3,1);//三行一列的网格布局管理器
p1.setLayout(g);//设置布局管理器
p1.add(p2);//将组建添加到面板中
p1.add(p3);
p1.add(p4);
p1.setBackground(new
Color(100,250,100));//更改面板颜色
btnLogin=new
JButton(“登录“);
btnCancel=new
JButton(“取消“);
btnLogin.addActionListener(this);
btnCancel.addActionListener(this);
BorderLayout
broder1=new
BorderLayout();
this.setLayout(broder1);
p5.add(btnLogin);
p5.add(btnCancel);
this.add(BorderLayout.SOUTH,p5);
this.add(BorderLayout.CENTER,p1);
this.setSize(350,250);
this.setTitle(“用户登录“);
this.setResizable(false);
this.setLocation(450,250);
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//关闭窗口
}
public
void
actionPerformed(ActionEvent
e){
JButton
button=(JButton)e.getSource();
if(button.equals(btnCancel)){
dispose();//如果客户按了登录和取消按钮,那么登录窗口就关闭
}
else{
LoginStart
Is=new
LoginStart();
Is.start();
this.dispose();
}
}
class
LoginStart
extends
Thread
{
public
void
run(){
int
port=Integer.parseInt(txtPort.getText());//取得端口号
String
ip=txtIP.getText();
String
nam=txtName.getText();
try{
toServer=new
Socket(ip,port);
in=new
BufferedReader(new
InputStreamReader(toServer.getInputStream()));
out=new
PrintStream(toServer.getOutputStream());//输出流
new
Client(out,in,nam);//如果登录成功,则弹出客户端聊天窗口
dispose();//同时关闭登录窗口
}
catch(Exception
e2){
System.out.println(“登录失败!“);
e2.printStackTrace();
}
}
}
public
static
void
main(String[]
args){
new
login();//启动登录窗口
}
}
六、
相关截图
登陆成功后,服务器界面显示:
踢出聊天室:
七、总结及体会
在设计的过程中了解到自己的知识比较有限,使得程序还不够完善,这一次的课程设计,让我懂得理论和实践相结合起来,从理论中得出结论,才能真正掌握这门技术,也提高了自己独立思考的能力,在设计的过程中,可以自己解决问题。真正体会到将一门知识学的更深入,必须加强实践,多练习,才能发现问题所在。