即时聊天系统.docx

上传人:b****8 文档编号:9992232 上传时间:2023-02-07 格式:DOCX 页数:30 大小:319.89KB
下载 相关 举报
即时聊天系统.docx_第1页
第1页 / 共30页
即时聊天系统.docx_第2页
第2页 / 共30页
即时聊天系统.docx_第3页
第3页 / 共30页
即时聊天系统.docx_第4页
第4页 / 共30页
即时聊天系统.docx_第5页
第5页 / 共30页
点击查看更多>>
下载资源
资源描述

即时聊天系统.docx

《即时聊天系统.docx》由会员分享,可在线阅读,更多相关《即时聊天系统.docx(30页珍藏版)》请在冰豆网上搜索。

即时聊天系统.docx

即时聊天系统

 

《网络应用程序设计》课程结业设计

 

课题名称:

并发服务器编程

组长:

丁成园

组员:

曹昀鑫,周峰江

学院:

计算机科学与工程学院

专业:

08网络工程

(1)班

学号:

090208124

指导教师:

李克清

提交日期:

2011/6/23

 

 

目录

1.引言......................................................................3

2.分析过程..................................................................3

2.1基本原理.............................................................3

2.2总体框架.............................................................3

3.开发过程4

3.1主要模块的详细设计...................................................5

3.11................................................................5

3.12................................................................5

3.13................................................................5

3.2运行.................................................................5

4.测试过程..................................................................9

5.实验小结..................................................................9

附录

1主要代码...................................................................11

1.1服务器主要代码.......................................................11

1.2客户端主要代码.......................................................17

2使用说明书.................................................................22

 

基于C#的聊天系统

1.引言

随着现在技术的不断输入和信息化得广泛普及,网络作为一种新兴事物,在近些年得到了前所未有的普及和深入,网络上的各种应用层出不穷,在各个阶层、各个年龄段得用户提供了不同的个性化的服务。

而现代中小型企业的领导认识到进一步提高企业信息化的必要性。

为使企业能在瞬间万变的信息时代生存下去,适应激烈的市场竞争,现在企业要求正加员工之间的交流和通信能力,尤其是领导和员工之间的共同能力,实时的交流系统就是在这种条件下诞生的。

系统开发时一个十分复杂的系统工程。

这里对系统开发的基本过程和方法进行介绍,列出相关的文档示例加以说明。

网络通信时网络应用的重要体现方面。

网上即时通信则是网络应用的重要体现方面。

本聊天系统主要应用于小型企业,学校或小型局域网内部使用。

本应用程序使短距离交流更加快捷和方便。

更能高效率的体现现代即时通信的特点。

2.分析过程

2.1基本原理

2.1.1服务器端

服务器启动后,将一直监听制定的端口。

看是否有客户端发来请求。

客户端如果要与服务器端建立连接,当客户端进行登录时,要向服务器端发送请求,将客户端的本地IP和端口号发送给服务器当服务器端接受到客户端发送来的请求后,会将客户端的资料储存在一个新的集合里,来满足其功能要求。

2.12客户端

当客户端建立于服务器端的连接后,就可以实现聊天的功能了。

任何一个客户端需要跟另一个客户联系时,客户端会将发送的内容、目标地址的IP地址和端口号一起发送给服务器,然后服务器会在socket对象中扫描出该目的地址并将客户端发送的内容再转发给目的地址。

2.13其他细节

在各个组件和容器中需要有事件处理的地方,比如关闭对话框,确定和取消等,要事先设置事件监听,和事件处理。

由于允许使用多个客户端,所以在各个套接字在接发信息时要用多线程,使接发信息的类继承Tread,实现多线程设计。

为了不使客户端和服务器端的程序代码过长,把各个类封装在不同的文件中,并都声明为公共类(public),这样可以在同一个包内访问。

委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递,这种将方法动态地赋给参数的做法,可以避免在程序中大量使用If-Else(Switch)语句,同时使得程序具有更好的可扩展性。

通过委托,实现了客户端能够不停地接收服务器发送来的信息,使得信息能够及时显示。

2.2总体框架

程序流程图

程序分析图

3.开发过程

3.1主要模块的详细设计

3.11登录

客户端首先登录,用户输入登录信息,点击“登录”按钮,如果服务器没有开启,显示“无法连接”的提示信息,如服务开启了,客户端根据接收的信息,调用数据库,查看数据库中是否存在此信息,如果不存在,显示出错信息;信息存在,向服务器发送登录信息,服务器接收信息后判断发现是登录信息,于是向数据库写入信息,此时写入的信息中的离线时间为空,客户端接收信息,同时调用数据库获得在线好友信息并回应给对应的客户端。

客户端接收服务器发来的信息,获得该用户的在线好友信息,进入聊天页面,同时将在线好友信息显示到好友列表中显示。

3.12聊天通信

客户端选择好友,在信息框中输入聊天信息,点击“发送”按钮时,首先在聊天框显示聊天内容,同时将信息送往服务器,服务器收到信息后,判断信息类型,是聊天信息,从信息中提取目的客户端的账号信息,根据账号信息,调用数据库,查看与其对应的IP地址和端口号,然后将信息重新打包发送往目的客户端,目的客户端收到服务器发来信息,根据源账号信息,得出对应的名称以便显示在聊天信息框中,同时将发送来的信息也一并显示在聊天信息框中。

3.13退出

客户端退出时,向服务器发送消息,服务器收到信息后,判断信息类型,得到是退出消息,获取当前时间,根据信息中的账号跟新数据库,将与此账号对应的且离线时间为空的信息条进行更新。

3.2运行

首先打开服务器客户端,点击打开服务器按钮,如图1所示。

图1服务器客户端

打开用户登录界面,并输入账号,密码,进入系统。

如图2所示。

用户登录界面

当用户111登录后,会显示如图3所示的聊天框,显示聊天信息和好友列表。

好友222登录后,用户111的登录界面会出现如图4所示。

图3用户111登录后聊天界面

图4用户222登录后聊天界面

这个时候,服务器会刷新所有在线用户列表如图5所示。

图5刷新用户列表后的服务器客户端

当用户退出后,会出现与服务器断开连接的提示框如图6所示。

图6用户退出界面

当用户111向用户222发送聊天信息时,用户111的聊天界面会显示如图7所示聊天信息,用户222接收到用户111发出的消息后,在聊天界面会出现如图8所示聊天信息。

图7用户111的聊天界面

图8用户222的聊天界面

4.测试过程

经过对系统的软、硬件的验收测试系统满足课题的要求。

其中硬件的测试主要包括硬件设备的清单、启动运行正常与否等。

重点是软件部分的测试,首先对软件的功能进行测试,然后再测试其稳定性。

系统功能测试细则表

序号

测试项目

功能与指标

测试方法

预期方法

测试结果

1

可登陆性

用户可以随时登陆,进入聊天室

按界面提示输入名称

出现主窗口和各个菜单项

正确完成

2

发出消息给好友

可以出送消息给好友

在消息框输入消息,并选择好友

好友收到消息

正确完成

3

接收到消息

用户能接收到其他好友发出的消息

当接收到数据时,在窗口显示

显示接收到的消息

正确完成

4

登陆后好友上线提示

在登陆状态下,能够接收到上线通知

启动多个客户端,连接到服务器端

其他好友显示上线

正确完成

5.实验小结

通过这次试验,我更加了解了关于C#编程过程中容易遇到的问题,以及系统的开发过程和检测,实践性的学习并使用了软件工程中学习到的知识,软件的制作全过程。

通过这次试验,让我受益匪浅。

 

附录

1.主要代码

1.1服务器主要代码

(1)变量定义:

privateTcpListenerServerListener;

//privateIPEndPointServerInfo;//存放服务器的IP和端口信息

privateSocketServerSocket;//服务端运行的SOCKETServerSocket

privateThreadListenThread;//服务端运行的线程

privateThreadAcceptThread;

privateArrayListClientsList;//为客户端建立的SOCKET连接

(2)“开启服务器”Click事件代码:

privatevoidbtnOpen_Click(objectsender,EventArgse)

{

ClientsList=newArrayList();

//新开一个监听线程

ListenThread=newThread(newThreadStart(ListenClients));

ListenThread.Start();

this.btnOpen.Enabled=false;

this.btnClose.Enabled=true;

}

(3)监听客户端:

privatevoidListenClients()

{

//监听

ServerListener=newTcpListener(IPAddress.Parse("10.18.46.7"),8000);

ServerListener.Start(10);

//新开一个socket去接收客户端

while(true)

{

try

{

SocketsktAccept=ServerListener.AcceptSocket();

ServerSocket=sktAccept;

AcceptThread=newThread(newThreadStart(MassageHandle));

AcceptThread.Start();

}

catch(Exception)

{

}

}

}

(4)信息接收处理:

privatevoidMassageHandle()

{

SocketsktAccept=ServerSocket;

ThreadtdAccept=AcceptThread;

string[]message=newstring[2];

byte[]bytes=newbyte[1024];

stringuid="";

IPEndPointie=(IPEndPoint)sktAccept.RemoteEndPoint;

boolbRcvMsg=true;

try

{

while(bRcvMsg)

{

Byte[]buffer=newByte[1024];

//接收子画面传过来的内容

intrec=sktAccept.Receive(buffer);

stringmsg=Encoding.ASCII.GetString(buffer,0,rec);

message=TransMessage(msg);

bytes=Encoding.ASCII.GetBytes(msg.ToCharArray());

uid=message[0].Trim().ToString();

if(message[1]!

=null)

{

stringname=GetSqlconStr.getName(uid);

if(message[1].Trim()=="ALL")

{//全发送

for(inti=0;i

{

SendMsgToClients((CList)ClientsList[i],msg);

}

//发送给单个客户端

}

else

{

stringmyid=message[1].Trim();

IPEndPointiep=GetSqlconStr.getEndPoint(myid);

for(inti=0;i

{

if(((IPEndPoint)((CList)ClientsList[i]).Sockt.RemoteEndPoint).Equals(iep))

{

SendMsgToClients((CList)ClientsList[i],msg);

break;

}

}

}

}

elseif(message[2].ToString()=="LoginIn")

{

//Invoke改变主机登录名单(增加登录机到主机名单List)

ChangeLb(uid,true);

for(inti=0;i

{

SendMsgToClients((CList)ClientsList[i],msg);

}

//新建一个CList类对象,加入到服务器的客户端列表

CListclient=newCList(message[0],sktAccept.RemoteEndPoint,tdAccept,sktAccept);

ClientsList.Add(client);

//给新登录的客户端发送已登录人的名单

stringuserList="List|";

for(inti=0;i

{

userList+=lbUsers.Items[i].ToString()+"|";

}

//buffer=Encoding.ASCII.GetBytes(userList.ToCharArray());

//给新登录的客户端发送登录人名单

SendMsgToClients(client,userList);

SqlConnectioncon1=newSqlConnection(GetSqlconStr.getConstring());

con1.Open();

stringsql1="insertintoLoginStatus(UserId,IpAddress,Port,LoginInTime,LoginOutTime)values('"+uid+"','"+ie.Address.ToString()+"','"+ie.Port.ToString()+"','"+DateTime.Now.ToString()+"',null)";

SqlCommandcmd1=newSqlCommand(sql1,con1);

cmd1.ExecuteNonQuery();

con1.Close();

}

//退出

elseif(message[2].ToString()=="LoginOut")

{

SqlConnectioncon2=newSqlConnection(GetSqlconStr.getConstring());

con2.Open();

stringsql2="updateLoginStatussetLoginOutTime='"+DateTime.Now.ToString()+"'whereUserId='"+uid+"'andLoginOutTimeisNULL";

SqlCommandcmd2=newSqlCommand(sql2,con2);

cmd2.ExecuteNonQuery();

con2.Close();

SqlConnectioncon3=newSqlConnection(GetSqlconStr.getConstring());

con3.Open();

stringsql3="updateUserssetStatus='离线'whereUserId='"+uid+"'";

SqlCommandcmd3=newSqlCommand(sql3,con3);

cmd3.ExecuteNonQuery();

con3.Close();

ChangeLb(uid,false);

intnRemove=0;

for(inti=0;i

{

if(((CList)ClientsList[i]).Sockt.RemoteEndPoint.ToString().Equals(sktAccept.RemoteEndPoint.ToString()))

{

nRemove=i;

bRcvMsg=false;

break;

}

}

sktAccept.Close();

ClientsList.Remove(ClientsList[nRemove]);

stringstrSendMsg=nRemove.ToString()+"||"+"LoginOut";

for(inti=0;i

{

buffer=Encoding.ASCII.GetBytes(strSendMsg);

//给新登录的客户端发送登录人名单

SendMsgToClients((CList)ClientsList[i],strSendMsg);

}

}

}

}

catch(Exception)

{

ListenThread.Abort();

ServerSocket.Close();

AcceptThread.Abort();

}

}

(5)服务器向客户端发送在线好友名单:

privatevoidSendMsgToClients(CListclient,stringMsg)

{

try

{

byte[]bufferToClient=Encoding.ASCII.GetBytes(Msg.ToCharArray());

client.Sockt.Send(bufferToClient);

}

catch(Exception)

{

}

finally

{

}

}

delegatevoidchangeLb(stringstr,boolbIsAdd);

//访问主线程

privatevoidChangeLb(stringstr,boolbIsAdd)

{

//invoke调用主线程

this.Invoke(newchangeLb(ChangeLbText),str,bIsAdd);

}

//设置主线程[界面]的值

privatevoidChangeLbText(stringstr,boolbIsAdd)

{

if(bIsAdd)

{

lbUsers.Items.Add(str);

}

else

{

lbUsers.Items.Remove(str);

}

}

(6)将收到的信息根据“|”分开,以便与判断信息类型:

privatestring[]TransMessage(stringtmsg)

{

intsum=0;

string[]reMessage=newstring[3];

char[]list=tmsg.ToCharArray();

for(inti=0;i

{

if(list[i]=='|'&&sum<2)

{

sum=sum+1;

}

else

{

reMessage[sum]+=Convert.ToString(list[i]);

}

}

returnreMessage;

}

(7)运行服务器时的初始设置:

privatevoidServer_Load(objectsender,EventArgse)

{

cmboxStatus.SelectedIndex=0;

this.btnOpen.Enabled=true;

this.btnClose.Enabled=false;

}

(8)信息刷新,以便于及时显示上线用户:

privatevoidRefresh(stringsql,DataGridViewdgw)

{

SqlConnectionconn=newSqlConnection(GetSqlconStr.getConstring());

conn.Open();

SqlCommandcmd=newSqlCommand(sql,conn);

SqlDataAdapterda=newSqlDataAdapter(cmd);

DataSetds=newDataSet("Users");

da.Fill(ds);

dgw.DataSource=ds.Tables[0];

conn.Close();

}

(9)根据条件选择显示对应的用户信息:

privatevoidcmboxStatus_SelectedIndexChanged(objectsender,EventArgse)

{

stringsql="";

if(cmboxStatus.SelectedItem.ToString()=="在线")

sql="select*fromUserswherestatus='在线'";

elseif(cmboxStatus.Sel

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 农林牧渔 > 林学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1