《计算机网络通信》课设.docx
《《计算机网络通信》课设.docx》由会员分享,可在线阅读,更多相关《《计算机网络通信》课设.docx(51页珍藏版)》请在冰豆网上搜索。
《计算机网络通信》课设
计算机网络通信课程设计
目录
(采用了WORD的目录功能,请同学查阅WORD的标题和目录使用方法,以便正确生成目录,模板中的分页符也不得随意删除,以免造成页眉和页码的错误)
设计总说明------------------------------------------------------------------------------------------------------------1
设计总说明I
1系统功能介绍1
1.1建立侦听服务:
1
1.2用户登录1
1.3收发聊天信息…………………………………………………………………………………
1.4收发系统消息3
1.5用户下线和通知3
1.6服务关闭3
2.代码实现3
2.1用户信息链表实现…………………………………………………………………
2.2服务器主框类架的实现5
2.3服务器侦听线程类的实现6
2.4服务器接收线程类的实现6
2.5客户端主框类的实现7
2.6客户端接收线程类的实现………………………………………………………
3附:
源程序8
参考文献9
设计总说明
这里主要用了java的网络编程相关知识,通过学习了解了TCP和UDP协议的基本知识和Socket编程的基本概念,以及TCP协议的响应流程,现在通过使用java提供的流Socket和数据包Socket,利用流Socket和数据包Socket建立通信连接,最后实现了一个完整的聊天程序,该聊天系统是基于TCP协议的流Socket实现的,它采用了典型的C/S架构,包括一个服务器应用程序和一个客户端程序,可以同时供多个用户进行聊天。
课程设计要求:
1登录功能。
客户端登录到聊天服务器,服务器管理所有登录的客户,并将客户列表发送给各个客户显示。
2客户可以通过服务器转发,实现一对一和多对多聊天。
3实现呼叫功能。
当客户端程序连接服务器时,通过服务器搜索所要呼叫的客户,如果检测到此用户且该用户正处于联网状态,则服务器通知此用户的客户端程序响应主叫方客户端程序,然后在主叫方和被叫方建立连接后,双方就可以聊天或进行其它的通信。
4客户端程序应该可以实时显示目前其它用户的状态(例如好友信息,上、下线)。
编写聊天程序
1系统功能介绍
本程序具有完整的会话功能,采用C/S结构,由两部分组成:
客户端和服务器,可以供多个用户进行聊天。
服务器具有建立侦听服务、转发聊天信息、响应用户下线、发送系统消息的功能;要实现这四个功能,需要建立以下四个类:
(1)用户信息链表、
(2)服务器主框类、(3)服务器侦听线程类、(4)服务器接收线程类。
客户端具有请求登录、请求下线、发送聊天信息、接收聊天信息、接收系统信息的功能。
要实现这些功能也要建立两个类——客户端主框架类和客户端接收线程类。
下面通过聊天系统的演示来具体了解聊天系统的功能。
1.1建立侦听服务:
初始状态的服务器如图
(1)所示,其主框架上具有两个按钮,分别用于启动和关闭服务器。
点击“启动”按钮处于允许状态,点击“关闭”按钮处于禁止状态;服务器启动后,就进入侦听状态,关闭就结束侦听,这里设计服务在8000端口启动。
图
(1)图
(2)
1.2用户登录
用户登录过程其实就是客服端请求登录和服务器响应登录两个过程。
初始状态的客户端如图(3),它的“上线”按钮用于用户登录,“下线”按钮用于用户下线,界面下方的JTextField控件,在用户未登录时输入用户名称,在用户登录后用于输入聊天信息,并按回车确定操作
图(3)
1.3收发聊天信息
这个过程包含了客户端发送聊天信息和服务器转发聊天信息。
当客户端登录后与其他在线用户进行聊天,只要在界面最底部的JTextField控件中输入聊天信息,按回车键就可以发送出去了,而那两个JComboBox控件分别用来选择聊天信息的对象和发送聊天信息的表情动作,“悄悄话”复选框用来标识此信息是否转发给非目标对象的其他在线用户。
1.4收发系统消息
系统信息的收发是单方面的,只能有服务器发给客户端,在服务器主界面输入系统信息,按回车键,系统就会将信息发送到所有客户端,客户端收到信息后就会显示在界面上。
如下图
1.5用户下线和通知
用户下线与用户登录一样,要涉及到客户端请求下线和服务器响应请求两个过程
用户单击客户端“下线”按钮,客户端就会向服务器发送下线请求,服务器接收后就胡释放与该用户的相关资源,并向其他用户发送该用户下线通知以及更新在线用户列表,如下图
1.6服务关闭
当服务器关闭服务时,就向所有在线用户发送服务器关闭信息,并且关闭所有与在线用户相连接的输入输出流和套接字,将且将界面调整到最初状态,如图()
客服端接收到服务器的关闭信息时,它将在界面上显示服务器关闭的提示信息,并且关闭与服务相连的输入输出流和套接字,删除在线用户列表,将界面调整到最初状态,
2.代码实现
2.1用户信息链表的实现
用户信息链表类(UserInfoList)需要对实现对用户信息的添加、删除和查询功能。
在实现UserInfoList类之前,先定义一个用于描述单个用户信息的数据结构Node类,并定义五个数据成员:
用户昵称、套接字、输入流、输出流和Next指针。
publicclassNode
{
Stringusername=null;//用户昵称
Socketsocket=null;//套接字
ObjectOutputStreamoutput=null;//输出流
ObjectInputStreaminput=null;//输入流
Nodenext=null;//保存链表中下一个节点的指针
}
在UserInfoList的构造函数中,对UserInfoList的成员变量进行初始化
publicUserInfoList()
{root=newNode();
root.next=null;//创建链表的节点
pointer=null;
count=0;}
为UserInfoList类添加成员函数add完成用户信息节点的添加功能。
publicvoidadd(Noden){
pointer=root;//将游标指向根节点
while(pointer.next!
=null){//判断是否链表尾部
pointer=pointer.next;}//将游标后移
pointer.next=n;//加入节点
n.next=null;
count++;}//计数器加一
为UserInfoList类添加成员函数del,完成用户信息节点的删除功能。
publicvoiddel(Noden){
pointer=root;//将游标指向根节点
while(pointer.next!
=null){//判断是否链表尾部
if(pointer.next==n){//判断当前节点是否为要删除节点
pointer.next=n.next;//删除节点
count--;//计数器减一
break;}
pointer=pointer.next;}}//将游标指向下一节点
为UserInfoList类添加成员函数getCount,提供返回链表中元素个数的功能:
publicintgetCount()
{
returncount;//返回当前链表中元素的个数
}
为UserInfoList类添加成员函数find,完成在用户信息链表中查找指定元素的功能,为方便起见,定义两个find函数,入口参数分别为String和int。
publicNodefind(Stringusername)
{
if(count==0)returnnull;
pointer=root;
while(pointer.next!
=null)
{
pointer=pointer.next;
if(pointer.username.equalsIgnoreCase(username))
{
returnpointer;
}
}
returnnull;
}
publicNodefind(intindex)
{
if(count==0)
{
returnnull;
}
if(index<0)
{
returnnull;
}
pointer=root;
inti=0;
while(i{
if(pointer.next!
=null)
{
pointer=pointer.next;
}
else
{
returnnull;
}
i++;
}
returnpointer;
}
}
2.2服务器主框类架的实现
服务器主框类架类需要实现人机交互功能、启动服务功能
关闭服务功能和发送系统信息功能。
需要为工程添加服务器主框类,名命为ServerFrame,在ServerFrame类的构造函数中,完成为服务器控件的添加、控件位置的调整、控件的初始状态的设定及控件事件侦听函数的添加。
添加函数init,在其中完成界面的初始化功能,在init函数中,除对事件进行添加和调整外,还对控件添加事件侦听器。
如为关闭服务按钮添加侦听器:
jbStopServer.addActionListener(
newActionListener()
{
publicvoidactionPerformed(ActionEvente)
{
stopServer();
}
}
);
在ServerFrame中添加starrServer函数完成启动服务的功能,添加stopServer函数完成关闭服务的功能,添加sendStopToAll函数依次向所有在线用户发送服务器关闭消息,添加sendSystemMessage函数实现发送系统消息的功能,添加sendMsgToAll函数完成向所有在线用户发送系统消息的功能。
2.3服务器侦听线程类的实现
服务器侦听线程类需要侦听客户端的登录请求,并且为该用户启动专用线程,处理与此用户相关的操作。
首先为工程添加ServerListenThread类,继承其父类Thread,在这个类中实现侦听客户端连接,并响应用户登录的功能。
在这个类中最重要的功能是在run函数中实现的,当服务器启动时,就会建立侦听线程,并且调用start函数开始运行线程。
publicvoidrun(){//服务器侦听线程的执行体
while(!
isStop&&!
server.isClosed())
{
try
{
client=newNode();//创建用户信息节点
client.socket=server.accept();//侦听客户端连接
client.output=newObjectOutputStream(client.socket.getOutputStream());
client.output.flush();//得到套接字输入输出流
client.input=newObjectInputStream(client.socket.getInputStream());
client.username=(String)client.input.readObject();
combobox.addItem(client.username);//读取用户昵称
userInfoList.add(client);
textarea.append("user"+client.username+"上线"+"\n");//显示提示信息
textfield.setText("在线用户"+userInfoList.getCount()+"人\n");
recvThread=newServerReceiveThread(
textarea,
textfield,
combobox,
client,
userInfoList);
recvThread.start();//启动线程
}
}
2.4服务器接收线程类的实现
服务器接收线程类需要接收客户端发来的信息,并且对该信息进行分析,执行相应操作。
当服务器收到客户端发来的聊天信息,对发送对象进行判断,如果发送对象是所有用户,则将信息发给所有用户,同理,如果是特定用户就发给特定用户。
当服务器接收到客户端发来的下线请求时,就关闭所有与该用户相关的输入输出流和套接字,并将该用户从在线列表中删除,此外,还需向所有在线用户发送该用户下线的通知和重发最新的列表。
首先为工程添加新类,命名为ServerReceiveThread,实现接收客户端信息的功能。
方法和侦听线程差不多。
它的成员函数sendToAll实现向所有在线用户转发聊天信息的功能,另一个成员函数sendUserList实现向所有在线用户发送用户列表的功能。
publicvoidsendToAll(Stringmsg)
{
intcount=userInfoList.getCount();
inti=0;
while(i{
Nodenode=userInfoList.find(i);
if(node==null)
{i++;
continue;
}
try
{
node.output.writeObject("聊天信息");
node.output.flush();
node.output.writeObject(msg);
node.output.flush();
}
2.5客户端主框类的实现
客户端主框架类实现了人机交互、用户登录、用户下线和聊天信息的发送功能。
客户端的主框架类为ClientFrame,其构造函数完成为客户端控件的添加、控件位置的调整、控件初始状态的设定以及控件事件侦听函数的添加。
成员函数LogIn完成用户登录功能,LogOut完成用户下线功能,SendMessage用于发送聊天信息。
publicvoidSendMessage()
{
StringtoSomebody=combobox.getSelectedItem().toString();
Stringstatus="";
if(checkbox.isSelected())
{
status="悄悄话";
}
Stringaction=actionlist.getSelectedItem().toString();
Stringmessage=textfield.getText();
if(socket.isClosed())
{
return;
}
try
{
output.writeObject("聊天信息");//发送聊天信息标识
output.flush();
output.writeObject(toSomebody);//发送聊天对象
output.flush();
output.writeObject(status);//发送聊天状态
output.flush();
output.writeObject(action);//发送聊天表情
output.flush();
output.writeObject(message);//发送聊天信息内容
output.flush();
2.6客户端接收线程类的实现
客户端接收线程类需要接收服务器发来的信息,并对该信息进行分析,执行相应的操作。
客户端收到的服务器信息有三种——聊天信息和系统信息、用户列表信息、服务关闭信息。
客户端将接收到聊天信息和系统信息显示在界面上,接收到用户信息就对信息进行分析,获取在线用户列表,显示在界面组合框中,接收到关闭信息,则执行关闭操作。
命名客户端接收线程类为ClientReceiveThread,实现接收服务器信息的功能,主要在run函数中实现该类的功能。
publicvoidrun()//线程执行体
{sendUserList();
while(!
isStop&&!
client.socket.isClosed())//若套接字没有关闭,则一直执行循环体
{
try{
Stringtype=(String)client.input.readObject();//读取服务器发送的聊天信息
if(type.equalsIgnoreCase("聊天信息")){//处理聊天信息
StringtoSomebody=(String)client.input.readObject();//获取系统信息内容
Stringstatus=(String)client.input.readObject();
Stringaction=(String)client.input.readObject();
Stringmessage=(String)client.input.readObject();
Stringmsg=client.username+action+"对"+toSomebody+
"说"+message+"\n";//显示信息
3附:
源程序
参考文献
【Java语言与面向对象程序设计】
【Java编程案例解析】
【计算机网络通信教程】
附录
(宋体小四号,1.25倍行距)(要求:
附录的有无根据情况需要而定,内容一般包括正文内不便列出的冗长公式推导、符号说明(含缩写)、计算机程序、图纸、表格等。
附录中有程序源代码的因篇幅限制可酌情考虑内容的字号。
)
//用户信息链表类
import.*;
importjava.io.*;
publicclassNode
{
Stringusername=null;
Socketsocket=null;
ObjectOutputStreamoutput=null;
ObjectInputStreaminput=null;
Nodenext=null;
}
importjavax.swing.*;
import.*;
importjava.io.*;
publicclassUserInfoList
{
Noderoot;
Nodepointer;
intcount;
publicUserInfoList()
{
root=newNode();
root.next=null;
pointer=null;
count=0;
}
publicvoidadd(Noden)
{
pointer=root;
while(pointer.next!
=null)
{
pointer=pointer.next;
}
pointer.next=n;
n.next=null;
count++;
}
publicvoiddel(Noden)
{
pointer=root;
while(pointer.next!
=null)
{
if(pointer.next==n)
{
pointer.next=n.next;
count--;
break;
}
pointer=pointer.next;
}
}
publicintgetCount()
{
returncount;
}
publicNodefind(Stringusername)
{
if(count==0)returnnull;
pointer=root;
while(pointer.next!
=null)
{
pointer=pointer.next;
if(pointer.username.equalsIgnoreCase(username))
{
returnpointer;
}
}
returnnull;
}
publicNodefind(intindex)
{
if(count==0)
{
returnnull;
}
if(index<0)
{
returnnull;
}
pointer=root;
inti=0;
while(i{
if(pointer.next!
=null)
{
pointer=pointer.next;
}
else
{
returnnull;
}
i++;
}
returnpointer;
}
}
//服务端主框架类
importjava.awt.*;
importjava.awt.event.*;
importjavax.swing.*;
importjavax.swing.event.*;
importjavax.swing.border.*;
importjava.io.*;
import.*;
publicclassServerFrameextendsJFrame
{
privateJButtonjbStartServer;
privateJButtonjbStopServer;
privateJButtonb1;
privateJScrollPanejs;
privateBorderborder;
privateServerSocketserverSocket;
privateJComboBoxcombobox;
privateJTextAreatextarea;
privateJTextFieldtextfield;
privateJTextFieldsystemMsg;
privateUserInfoListuserInfoList;
privateServerListenThreadlistenThread;
publicServerFrame()
{
super("服务端");
init();
setSize(370,570);
show();