Java网络编程实践报告

时间:2024.4.27

Java网络编程实践(基于C/S的控制台聊天室 )

课程设计说明书

课程名称:Java网络课程实践

题目:基于C/S的控制台聊天室

姓名:***

学号:***

教学班号:01

指导教师:***

兰州交通大学软件科学与工程系

二○XX 年 月 日

任务书:

题目 3:基于C/S的控制台聊天室(1人)

实现几个客户端的群聊(在控制台窗口显示聊天信息),信息经服务端转发和群发,多客户端使用多线程。基于Socket。注意:在每一个客户端窗口要显示所有参与聊天者的聊天内容,包括谁发言及发言内容。

文档内容要求:

1、在做上述题目时,正文要求包含4部分内容:1)项目简述和目的 2)解题基本思路;3)分析和设计 4)主要程序源代码;5)运行截图;5)总结和体会

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<String,Socket> container=new HashMap<String,Socket>(); //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&& msg!=""){//如果消息不为空

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("");

}

}

});//end

//刷新按钮监听器

flushButton.addActionListener(new ActionListener(){

public void actionPerformed(ActionEvent e){

if(list!=null){

list.removeAll(); //清空在线用户列表,以便刷新

}

Set<Map.Entry<String,Socket>> mySet=container.entrySet();

for(Iterator<Map.Entry<String,Socket>> it=mySet.iterator();it.hasNext();){//刷新列表

Map.Entry<String,Socket> 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&& !server.isClosed()){

area.append("警告!服务器已在启动中!\n");

}

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<3){

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+"");

singleCom(time+"[系统消息]:警告,请注意文明用语!",client);

area.append(time+"[系统消息]:"+name+"第"+mark+"次使用了不文明用语,特此警告!");

}

else{//如果客户第三次说不文明的话,系统就把他踢出聊天室

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+"");

if(mark==3){

singleCom(time+"[系统消息]:"+name+"由于多次使用了不文明用语,经警告无效,现已被踢出聊天室!",client);//告诉他本人

}

removeClient(name,client);//从系统列表中删除这个人的信息

//并向所有人广播这一消息

broadcast(time+"[系统消息]:"+name+"由于多次使用了不文明用语,经警告无效,现已被踢出聊天室!\n");

area.append(time+"[系统消息]:"+name+"由于多次使用了不文明用语,经警告无效,现已被踢出聊天室!");

}

}

else{

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+"");

area.append(time+name+"说"+msg+"\n\n");//同时向每个在线客户广播这则消息

}

}

}

}

catch(Exception ex){

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+"");

area.append(time+name+"下线了!\n");

broadcast(time+name+"下线了!\n");

list.remove(name+"---"+client.getInetAddress().getHostAddress());

container.remove(name);

}

}

}

void removeClient(String name,Socket client){

list.remove(name+"---"+client.getInetAddress().getHostAddress());

container.remove(name);

}

void broadcast(String msg){//broadcast---begin

Set<Map.Entry<String,Socket>> mySet=container.entrySet();

Iterator<Map.Entry<String,Socket>> it=mySet.iterator();

String message=msg;

while(it.hasNext()){//如果列表中还有客户

Map.Entry<String,Socket> 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();//启动登录窗口

}

}

六、 相关截图

Java网络编程实践报告

Java网络编程实践报告

Java网络编程实践报告

登陆成功后,服务器界面显示:

Java网络编程实践报告

踢出聊天室:

Java网络编程实践报告

七、总结及体会

在设计的过程中了解到自己的知识比较有限,使得程序还不够完善,这一次的课程设计,让我懂得理论和实践相结合起来,从理论中得出结论,才能真正掌握这门技术,也提高了自己独立思考的能力,在设计的过程中,可以自己解决问题。真正体会到将一门知识学的更深入,必须加强实践,多练习,才能发现问题所在。

更多相关推荐:
Java网络编程实验报告

惠州学院计算机科学系网络工程专业SoftwareEngineeringLaboratoryDeptofComputerScienceandTechnologyHuihzouUniversityTELampFAX...

java网络编程实验报告

实验一Application与Applet程序调试运行实验目的熟悉所用系统的上机方法与步骤实验内容编写一个JavaApplication和一个Applet程序输出以下信息HelloJavaWorld1JavaA...

java聊天室实验报告 网络编程技术实验报告

网络编程技术大作业修改履历目录1文档概述...41.1文档目的和范围...41.2术语/缩略语...41.3参考文档...52系统概述...52.1项目说明...52.2需求分析...52.3可行性或难点分析.…

网络编程实验报告

网络编程技术实验报告一实验目的网络编程技术是计算机科学与技术专业网络工程专业软件工程专业的一门专业基础课程本课程以Java技术为主讲授Java语言是当前最流行的网络编程语言本课程是一门实用性和综合运用性都很强的...

Java网络编程实验一到四答案

实验一开发工具和语言基础By光绪一实验目的和要求1掌握JDK的安装环境配置和使用掌握JBuilder或Eclips的安装和使用使用JDKJBuilder或Eclips编辑编译和运行Java程序2掌握Java的语...

网络编程实验 java即时聊天程序

高级网络编程实验报告实验名称即时聊天工具实验日期20xx15学生姓名学生学号一实验目的加深对网络编程中客户端和服务器的包的传送和接收在实验中学习Socket网络编程二实验环境OSWindows编程语言java开...

陈振辉&&虞在洋网络编程聊天程序报告

网络编程实验报告C语言编写聊天程序学号姓名姓名专业班级Winform平台陈振辉虞在洋计算机科学与技术一实验目的1熟悉和掌握网络编程的基本方法和步骤2进一步理解clientserver交互模式3加深学生对于网络协...

6.Java网络编程实验-多线程

Java网络编程实验报告实验六学号姓名实验项目名称多线程教师评分

实验七 Java网络编程技术

实验7Java网络编程技术一实验目的1掌握基于TCP的socket编程的方法2熟悉ServerSocketSocket和InetAddress类的使用3熟悉URL类的使用URL的概念和编程二实验内容1使用Ine...

Java程序设计网络编程实验指导书

Java程序设计与网络编程实验指导书一实验教学目的内容和要求1实验教学目的Java语言及网络编程实验是将课程教学中所讲授知识与实践相联系的重要环节通过实验加深学生对所学知识的理解和认识增强实践能力促进学生熟悉J...

Java网络编程复习要点及实验

1对非可序列化对象调用序列化和反序列化方法会抛出IOExceptiontransient变量不会被序列化Static变量不会被初始化Externalizable接口中声明了两个方法publicvoidwrite...

实验08 Java之网络编程

实验七网络编程1实验目的1掌握Socket通信2掌握UDP通信2实验内容实验题1利用Socket类和ServerSocket类编写一个CS程序实现CS通信客户端向服务器端发送Time命令服务器端接受到该字符串后...

java网络编程实验报告(16篇)