




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、& rf * 4 itCHANG SHU INSTITUTE OF TECHNOLOGY网络应用程序设计课程结业设计课题名称:并发服务器编程组 长:丁成园组 员:曹日匀鑫,周峰江学 院:计算机科学与工程学院专 业:08网络工程(1)班学 号: 090208124指导教师:李克清提交日期: 2011/6/23i目录1. 弓I言32. 分析过程32.1基本原理32.2总体框架33. 开发过程43.1主要模块的详细设计 53.11 53.12 53.13 53.2运行54. 测试过程95. 实验小结9附录1主要代码111.1服务器主要代码 111.2客户端主要代码 172使用说明书2223基
2、于C#勺聊天系统1. 引言随着现在技术的不断输入和信息化得广泛普及,网络作为一种新兴事物,在近些年得 到了前所未有的普及和深入,网络上的各种应用层出不穷,在各个阶层、各个年龄段得用户提供了不同的个性化的服务。而现代中小型企业的领导认识到进一步提高企业信息化的必要 性。为使企业能在瞬间万变的信息时代生存下去,适应激烈的市场竞争,现在企业要求正加员工之间的交流和通信能力,尤其是领导和员工之间的共同能力,实时的交流系统就是在这种条件下诞生的。系统开发时一个十分复杂的系统工程。这里对系统开发的基本过程和方法进行介绍,列出相关的文档示例加以说明。网络通信时网络应用的重要体现方面。网上即时通信则是网络应用
3、的重要体现方面。 本聊天系统主要应用于小型企业,学校或小型局域网内部使用。本应用程序使短距离交流更加快捷和方便。更能高效率的体现现代即时通信的特点。2. 分析过程2.1基本原理2.1.1服务器端服务器启动后,将一直监听制定的端口。 看是否有客户端发来请求。客户端如果要与服 务器端建立连接,当客户端进行登录时,要向服务器端发送请求,将客户端的本地IP和端口号发送给服务器当服务器端接受到客户端发送来的请求后,会将客户端的资料储存在一个新的集合里,来满足其功能要求。2.12客户端当客户端建立于服务器端的连接后,就可以实现聊天的功能了。 任何一个客户端需要跟另一个客户联系时,客户端会将发送的内容、目标
4、地址的IP地址和端口号一起发送给服务器,然后服务器会在 socket对象中扫描出该目的地址并将客户端发送的内容再转发给目的 地址。2.13其他细节在各个组件和容器中需要有事件处理的地方,比如关闭对话框,确定和取消等,要事先设置事件监听,和事件处理。由于允许使用多个客户端,所以在各个套接字在接发信息时要用多线程,使接发信息的类继承Tread,实现多线程设计。为了不使客户端和服务器端的程序代码过长,把各个类封装在不同的文件中,并都声明为公共类(public),这样可以在同一个包内访问。委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的 参数来进行传递,这种将方法动态地赋给参数的做法,
5、可以避免在程序中大量使用 If-Else(Switch)语句,同时使得程序具有更好的可扩展性。通过委托,实现了客户端能 够不停地接收服务器发送来的信息,使得信息能够及时显示。2.2总体框架程序流程图操作:操作:操作:登录信息响应消息聊天消息 信息提取,判断信息正确性 信息提取,得到消息接收方 消息接收并显不' 发送消息3.开发过程3.1主要模块的详细设计3.11登录客户端首先登录,用户输入登录信息,点击“登录”按钮,如果服务器没有开启,显示“无法连接”的提示信息,如服务开启了,客户端根据接收的信息,调用数据库,查看数据 库中是否存在此信息,如果不存在,显示出错信息;信息存在,向服务器发
6、送登录信息,服 务器接收信息后判断发现是登录信息,于是向数据库写入信息, 此时写入的信息中的离线时间为空,客户端接收信息,同时调用数据库获得在线好友信息并回应给对应的客户端。客户端接收服务器发来的信息,获得该用户的在线好友信息,进入聊天页面,同时将在线好友信息显示到好友列表中显示。3.12聊天通信客户端选择好友,在信息框中输入聊天信息,点击“发送”按钮时,首先在聊天框显示 聊天内容,同时将信息送往服务器,服务器收到信息后,判断信息类型,是聊天信息,从信 息中提取目的客户端的账号信息,根据账号信息,调用数据库,查看与其对应的IP地址和端口号,然后将信息重新打包发送往目的客户端,目的客户端收到服务
7、器发来信息,根据源账号信息,得出对应的名称以便显示在聊天信息框中,同时将发送来的信息也一并显示在聊天信息框中。3.13退出客户端退出时,向服务器发送消息, 服务器收到信息后, 判断信息类型,得到是退出消 息,获取当前时间,根据信息中的账号跟新数据库,将与此账号对应的且离线时间为空的信息条进行更新。3.2运行首先打开服务器客户端,点击打开服务器按钮,如图 1所示。图1服务器客户端打开用户登录界面,并输入账号,密码,进入系统。如图2所示。当用户111登录后,会显示如图3所示的聊天框,显示聊天信息和好友列表。好友222登 录后,用户111的登录界面会出现如图 4所示。图3用户111登录后聊天界面0.
8、好友列表111 i5 Qnlin«!222 13 online!在线好友:顷1口2零退出岌谖信息图4用户222登录后聊天界面这个时候,服务器会刷新所有在线用户列表如图5所示。图5刷新用户列表后的服务器客户端当用户退出后,会出现与服务器断开连接的提示框如图6所示。/ <好度列衰Ijll is fthUn*!“在In In I 1I ta I 1201122:1 1241 i发送值息发送信思222图6用户退出界面当用户111向用户222发送聊天信息时,用户 111的聊天界面会显示如图 7所示聊天信息, 用户222接收到用户111发出的消息后,在聊天界面会出现如图8所示聊天信息。图7
9、用户111的聊天界面图8用户222的聊天界面4.测试过程经过对系统的软、硬件的验收测试系统满足课题的要求。其中硬件的测试主要包括硬件设备的清单、启动运行正常与否等。重点是软件部分的测试, 首先对软件的功能进行测试, 然后再测试其稳定性。系统功能测试细则表序号测试项目功能与指标测试方法预期方法测试结果1可登陆性用户可以随时登陆, 进入聊天室按界面提示输入名称出现主窗口 和各个菜单 项正确完成2发出消息给 好友可以出送消息给好友在消息框输 入消息,并选 择好友好友收到消 息正确完成3接收到消息用户能接收到其他好友发出的消息当接收到数据时,在窗口显示显示接收到 的消息正确完成4登陆后好友 上线提不&
10、#39;在登陆状态下,能够 接收到上线通知启动多个客户端,连接到服务器端其他好友显 示上线正确完成5.实验小结通过这次试验,我更加了解了关于C#编程过程中容易遇到的问题,以及系统的开发过程和检测,实践性的学习并使用了软件工程中学习到的知识,软件的制作全过程。 通过这次试验,让我受益匪浅。附录1. 主要代码1.1服务器主要代码(1)变量定义:private TcpListener ServerListener;/private IPEndPoint Serverinfo;/ 存放服务器的 IP和端口信息private Socket ServerSocket;/服务端运行的 SOCKETServe
11、rSocketprivate Thread ListenThread;/服务端运行的线程 private Thread AcceptThread;private ArrayList ClientsList; /为客户端建立的 SOCKET 连接(2) “开启服务器”Click事件代码:private void btnOpen_Click( object sender, EventArgs e)(ClientsList = new ArrayList ();/新开一个监听线程ListenThread = new Thread(new ThreadStart(ListenClients);List
12、enThread.Start();this .btnOpen.Enabled = false;this .btnClose.Enabled = true;(3) 监听客户端:private void ListenClients()(/监听ServerListener = new TcpListener (IPAddress.Parse('"), 8000);ServerListener.Start(10);新开一个socket去接收客户端while (true)(try(Socket sktAccept = ServerListener.AcceptSoc
13、ket();ServerSocket = sktAccept;AcceptThread = new Thread(new ThreadStart(MassageHandle);AcceptThread.Start();catch (Exception)(4) 信息接收处理: private void MassageHandle()(Socket sktAccept = ServerSocket;Thread tdAccept = AcceptThread;string message = new string 2;byte口 bytes = new byte1024;string uid =&
14、quot;"IPEndPoint ie = (IPEndPoint)sktAccept.RemoteEndPoint;bool bRcvMsg = true;try(while (bRcvMsg)(Byte buffer = new Byte1024;接收子画面传过来的内容int rec=sktAccept.Receive(buffer);string msg = Encoding .ASCII.GetString(buffer, 0, rec);message = TransMessage(msg);bytes = Encoding .ASCII.GetBytes(msg.ToCh
15、arArray();uid = message0.Trim().ToString();if (message1 != null)(string name = GetSqlconStr.getName(uid);if (message1.Trim() = "ALL")(全发送for (int i = 0; i < ClientsList.Count; i+)(SendMsgToClients( CList)ClientsListi, msg);发送给单个客户端else(string myid = message1.Trim();IPEndPoint iep = GetS
16、qlconStr.getEndPoint(myid);for (int i = 0; i < ClientsList.Count; i+)(if(IPEndPoint)(CList )ClientsListi).Sockt.RemoteEndPoint).Equals(iep)(SendMsgToClients( CList)ClientsListi, msg); break; else if (message2.ToString() = "LoginIn") (/Invoke改变主机登录名单(增加登录机到主机名单List)ChangeLb(uid, true);fo
17、r (int i = 0; i < ClientsList.Count; i+)(SendMsgToClients( CList )ClientsListi, msg);新建一个CList类对象,加入到服务器的客户端列表CList client = new CList(message0, sktAccept.RemoteEndPoint, tdAccept, sktAccept);ClientsList.Add(client);给新登录的客户端发送已登录人的名单string userList = "List|"for (int i = 0; i < this.l
18、bUsers.Items.Count; i+)(userList += lbUsers.Itemsi.ToString() +"|"/buffer = Encoding.ASCII.GetBytes(userList.ToCharArray();给新登录的客户端发送登录人名单SendMsgToClients(client, userList);SqlConnection coni = newSqlConnection (GetSqlconStr.getConstring();con1.Open();string sqll = "insert into LoginS
19、tatus(UserId,IpAddress,Port,LoginInTime,LoginOutTime) values('" + uid + "','" + ie.Address.ToString() + "','" + ie.Port.ToString() + "','" + DateTime.Now.ToString() + "',null)"SqlCommand cmdl = new SqlCommand(sqll, coni);cm
20、d1.ExecuteNonQuery();con1.Close();退出else if (message2.ToString() = "LoginOut")(SqlConnection con2 = newSqlConnection (GetSqlconStr.getConstring();con2.Open();string sql2 = "update LoginStatus set LoginOutTime='" + DateTime .Now.ToString() + "' where UserId='"
21、; + uid + "' and LoginOutTime is NULL"SqlCommand cmd2 = new SqlCommand (sql2, con2);cmd2.ExecuteNonQuery();con2.Close();SqlConnection con3 = newSqlConnection (GetSqlconStr.getConstring();con3.Open();string sql3 = "update Users set Status=离线'where UserId='" + uid +;Sql
22、Command cmd3 = new SqlCommand (sql3, con3);cmd3.ExecuteNonQuery();con3.Close();ChangeLb(uid, false);int nRemove = 0;for (int i = 0; i < ClientsList.Count; i+)if(CList )ClientsListi).Sockt.RemoteEndPoint.ToString().Equals(sktAccept.RemoteEndPoint.ToString()nRemove = i;bRcvMsg = false;break;sktAcce
23、pt.Close();ClientsList.Remove(ClientsListnRemove);string strSendMsg = nRemove.ToString() + "|" + "LoginOut"for (int i = 0; i < ClientsList.Count; i+) buffer = Encoding .ASCII.GetBytes(strSendMsg);给新登录的客户端发送登录人名单SendMsgToClients( CList )ClientsListi, strSendMsg);catch (Exceptio
24、n )ListenThread.Abort();ServerSocket.Close();AcceptThread.Abort();(5) 服务器向客户端发送在线好友名单:private void SendMsgToClients( CList client, string Msg)try byte bufferToClient = Encoding .ASCII.GetBytes(Msg.ToCharArray();client.Sockt.Send(bufferToClient);catch (Exception)(finally(delegate void changeLb(string
25、 str, bool bIsAdd);/访问主线程private void ChangeLb( string str, bool bIsAdd)(/invoke调用主线程this.Invoke( new changeLb(ChangeLbText), str, bIsAdd); 设置主线程界面的值private void ChangeLbText( string str, bool bIsAdd)(if (bIsAdd)(lbUsers.Items.Add(str);else(lbUsers.Items.Remove(str);(6) 将收到的信息根据“ |”分开,以便与判断信息类型: pri
26、vate string TransMessage( string tmsg)(int sum = 0;string reMessage = new string 3;char list = tmsg.ToCharArray();for (int i = 0; i < list.Length; i+)(if (listi = '|' && sum < 2)(sum = sum + 1;else(reMessagesum += Convert .ToString(listi);return reMessage;(7) 运行服务器时的初始设置:privat
27、e void Server_Load( object sender, EventArgs e)cmboxStatus.SelectedIndex = 0;this .btnOpen.Enabled = true;this .btnClose.Enabled = false;(8) 信息刷新,以便于及时显示上线用户:private void Refresh(string sql, DataGridView dgw)SqlConnection conn = new SqlConnection (GetSqlconStr.getConstring();conn.Open();SqlCommand c
28、md = new SqlCommand(sql, conn);SqlDataAdapter da = new SqlDataAdapter (cmd);DataSet ds = new DataSet("Users");da.Fill(ds);dgw.DataSource = ds.Tables0;conn.Close();(9) 根据条件选择显示对应的用户信息:private void cmboxStatus_SelectedIndexChanged( object sender, EventArgs e)string sql =""if (cmbox
29、Status.SelectedItem.ToString()="在线")sql = "select * from Users where status='在线'"else if (cmboxStatus.SelectedItem.ToString()="离线")sql = "select * from Users where status='离线'"elsesql = "select * from Users"Refresh(sql, dgwDisplay);(1
30、0) “关闭服务器” Click事件:private void btnClose_Click( object sender, EventArgs e)OnClosed(e);this.Close();(11)关闭所有套接字以及线程资源:protected override void OnClosed( EventArgs e)if (ClientsList != null)(for (int i = 0; i < ClientsList.Count; i+)(CList)ClientsListi).Sockt.Close();(CList)ClientsListi).Thread.Abo
31、rt();if (AcceptThread != null)(AcceptThread.Abort();if (ServerSocket != null)(ServerSocket.Close();if (ListenThread != null)(ListenThread.Abort();if (ServerListener != null)(ServerListener.Stop();base.OnClosed(e);1.2客户端主要代码登录窗体(1)变量定义:byte bytes;byte sendmsg;private Socket localsocket;private IPAddr
32、ess serIp;private IPEndPoint iep;string uid;/int i=0;(2) “登录”按钮的 Click事件:private void btnLogin_Click( object sender, EventArgs e)(if (txtID.Text = "" | txtPasswd.Text ="")(MessageBox.Show(”登陆不正确!请输入完整信息!");return; else(SqlConnection con = new SqlConnection(GetSqlStr.getConst
33、ring(); con.Open();string sql = "select * from Users where UserId = '" + txtID.Text.Trim() + "' and Passwd = '" + txtPasswd.Text.Trim() + "'”;SqlCommand cmd = new SqlCommand (sql, con);SqlDataReader dr = cmd.ExecuteReader();if (!dr.Read()(MessageBox.Show(&quo
34、t;信息输入错误!");con.Close();return; else (uid = txtID.Text.ToString();byte口 bytes = new byte65535;string msg = uid + "|" + "|LoginIn”;bytes = Encoding .ASCII.GetBytes(msg.ToCharArray();localsocket = new Socket(AddressFamily .InterNetwork, SocketType .Stream, ProtocolType .Tcp);try(lo
35、calsocket.Connect( IPAddress.Parse('" ),8000);localsocket.Send(bytes);SqlConnection conn = newSqlConnection (GetSqlStr.getConstring();conn.Open();string sql2 = "update Users set Status=在线'where UserId='" + uid +;SqlCommand cmd2 = new SqlCommand (sql2, conn);cmd2.
36、ExecuteNonQuery();conn.Close();UserList ulist = new UserList (localsocket, uid);this.Hide();ulist.Show();catch ( SocketException )(MessageBox.Show("服务器出现问题,连接服务器失败!");return;private void Form1_Load( object sender, EventArgs e)(bytes = new byte1024;sendmsg = new byte1024;聊天框(1)变量定义:定义委托用于跨线
37、程改变接收信息和好友列表的值delegate void ChangeTxtMsg (string str);delegate void changeClb(string str, int nType, int nIndex);private bool mLogIn = false;private Socket Clientsocket;private Thread MsgHandleThread;string uid;byte sendmsg=new byte1024;(2) “发送消息”按钮 Click事件:private void btnSendMsg_Click( object send
38、er, EventArgs e)(string msg;int temp = 0;byte sendmsg = new byte1024;changeTxtMsg("我说:n" + txtSendMsg.Text.ToString() + "n");try(if (clbFriendMsg.SelectedItems.Count >= 1) 判断消息是群发还是发送给 指定好友(string friendID = clbFriendMsg.SelectedItem.ToString();msg = uid + "|" + frie
39、ndID + "|" + txtSendMsg.Text.ToString();sendmsg = Encoding .ASCII.GetBytes(msg.ToCharArray();Clientsocket.Send(sendmsg);else(for (int i = 0; i < clbFriendMsg.Items.Count; i+)(if (clbFriendMsg.GetItemChecked(i)(temp+;if (temp = clbFriendMsg.Items.Count)(msg = uid + "|ALL|" + tx
40、tSendMsg.Text.Trim();sendmsg = Encoding .ASCII.GetBytes(msg.ToCharArray();catch(changeTxtMsg(""' + txtSendMsg.Text.ToString() + "'信息发送失败!n");finally(txtSendMsg.Text ="”;(3) 接收信息处理:private void HandleReceivedMsg()(bool bReceive = true;string name, reMsg;/存放信息发送目标好友的信息
41、 while (bReceive)(try(Socket AcReceive = Clientsocket;Byte buff = new Byte2048;int rec=AcReceive.Receive(buff);reMsg = Encoding .ASCII.GetString(buff,0,rec);string UserArrList = reMsg.Split( '|');if (reMsg !="")(string message = TransMessage(reMsg);if(UserArrList0.Equals( "Lis
42、t")(ChangeClb(string.Empty, 0, -1);for (int i = 1; i < UserArrList.Length -1; i+)(ChangeClb(UserArrListi, 1, -1);changeTxtMsg(UserArrListi + " is online!n" );if (message1.Trim() = "" && message2.Equals( "LoginIn") (name = GetSqlStr .getName(message0);ChangeClb(message0, 1, -1);changeTxtMsg(name + "上线了
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025-2030工业软件产业市场发展现状及投资机会分析研究报告
- 2025-2030工业视觉检测机器人应用领域拓展与商业模式创新研究报告
- 2025-2030工业物联网安全防护体系构建与攻击仿真测试报告
- 水果冻干加工厂创新创业项目商业计划书
- 坚果碎即食调料创新创业项目商业计划书
- 夏威夷果冰淇淋风味创新创业项目商业计划书
- 手指玫瑰创新创业项目商业计划书
- 橡胶制品质量检测中心创新创业项目商业计划书
- 情感智能与社交技能培训创新创业项目商业计划书
- 创业投资协议书标准范文
- 饮品运输行业分析
- 白鹿原名著导读读书分享
- 定密理论与实务3定密的依据课件
- 同济大学信纸
- 交通运输工程施工安全监管台帐(参考)用表样表分享
- 建筑消能减震设计技术及工程实例讲解
- 电梯控制技术PPT完整全套教学课件
- 国开电大《工程数学(本)》形成性考核作业5答案
- LS/T 1201-2020磷化氢熏蒸技术规程
- HY/T 053-2001微孔滤膜
- GB/T 4798.5-2007电工电子产品应用环境条件第5部分:地面车辆使用
评论
0/150
提交评论