ImageVerifierCode 换一换
格式:DOC , 页数:25 ,大小:969.50KB ,
资源ID:2486810      下载积分:10 金币
快捷注册下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

开通VIP
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.zixin.com.cn/docdown/2486810.html】到电脑端继续下载(重复下载【60天内】不扣币)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

开通VIP折扣优惠下载文档

            查看会员权益                  [ 下载后找不到文档?]

填表反馈(24小时):  下载求助     关注领币    退款申请

开具发票请登录PC端进行申请

   平台协调中心        【在线客服】        免费申请共赢上传

权利声明

1、咨信平台为文档C2C交易模式,即用户上传的文档直接被用户下载,收益归上传人(含作者)所有;本站仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。所展示的作品文档包括内容和图片全部来源于网络用户和作者上传投稿,我们不确定上传用户享有完全著作权,根据《信息网络传播权保护条例》,如果侵犯了您的版权、权益或隐私,请联系我们,核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
2、文档的总页数、文档格式和文档大小以系统显示为准(内容中显示的页数不一定正确),网站客服只以系统显示的页数、文件格式、文档大小作为仲裁依据,个别因单元格分列造成显示页码不一将协商解决,平台无法对文档的真实性、完整性、权威性、准确性、专业性及其观点立场做任何保证或承诺,下载前须认真查看,确认无误后再购买,务必慎重购买;若有违法违纪将进行移交司法处理,若涉侵权平台将进行基本处罚并下架。
3、本站所有内容均由用户上传,付费前请自行鉴别,如您付费,意味着您已接受本站规则且自行承担风险,本站不进行额外附加服务,虚拟产品一经售出概不退款(未进行购买下载可退充值款),文档一经付费(服务费)、不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
4、如你看到网页展示的文档有www.zixin.com.cn水印,是因预览和防盗链等技术需要对页面进行转换压缩成图而已,我们并不对上传的文档进行任何编辑或修改,文档下载后都不会有水印标识(原文档上传前个别存留的除外),下载后原文更清晰;试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓;PPT和DOC文档可被视为“模板”,允许上传人保留章节、目录结构的情况下删减部份的内容;PDF文档不管是原文档转换或图片扫描而得,本站不作要求视为允许,下载前可先查看【教您几个在下载文档中可以更好的避免被坑】。
5、本文档所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用;网站提供的党政主题相关内容(国旗、国徽、党徽--等)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
6、文档遇到问题,请及时联系平台进行协调解决,联系【微信客服】、【QQ客服】,若有其他问题请点击或扫码反馈【服务填表】;文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“【版权申诉】”,意见反馈和侵权处理邮箱:1219186828@qq.com;也可以拔打客服电话:0574-28810668;投诉电话:18658249818。

注意事项

本文(基于Socket聊天室(C#版).doc)为本站上传会员【a199****6536】主动上传,咨信网仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知咨信网(发送邮件至1219186828@qq.com、拔打电话4009-655-100或【 微信客服】、【 QQ客服】),核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载【60天内】不扣币。 服务填表

基于Socket聊天室(C#版).doc

1、一、服务器/客户端聊天室模型 1.首先启动聊天室服务器,使得TcpListener开始监听端口,此时TcpListener会进入Pending状态,等待客户端连接; 2.其次,当有客户端连接后,通过AccepSocket返回与客户端连接的Socket对象,然后通过读写Socket对象完成与聊天室客户端的数据传输。聊天室客户端成功启动后,首先创建一个Socket对象,然后通过这个Socket对象连接聊天室服务器,连接成功后开通Socket完成数据的接收和发送处理。 二、系统功能设计 本设计为一个简单的聊天室工具,设计基本的聊天功能,如聊天、列表维护等。系统主要为两大块:聊天室服务

2、器及聊天室客户端。 服务器界面设计如下: 客户端界面设计如下: 三、聊天协议的应答 A—网络—B 主机与主机通信主要识别身份(标识设备用IP)及通信协议 网络应用程序——端口号——接收数据 注:1.IP地址是总机,端口号是分机(传输层) 2.端口号为16位二进制数,范围0到65535,但实际编程只能用1024以上端口号 Socket编程 首先,我们了解常用网络编程协议。我们用得最多的协议是UDP和TCP,UDP是不可靠传输服务,TCP是可靠传输服务。UDP就像点对点的数据传输一样,发送者把数据打包

3、包上有收信者的地址和其他必要信息,至于收信者能不能收到,UDP协议并不保证。而TCP协议就像(实际他们是一个层次的网络协议)是建立在UDP的基础上,加入了校验和重传等复杂的机制来保证数据可靠的传达到收信者。一个是面向连接一个无连接,各有用处,在一些数据传输率高的场合如视频会议倾向于UDP,而对一些数据安全要求高的地方如下载文件就倾向于TCP。 Socket————网络应用程序 电话机————访问通信协议 聊天协议的应答: 聊天状态:CLOSED和CONNECTED状态 执行CONN命令后进入CONNECTED状态,执行下列命令: CONN:连接聊天室服务器 JO

4、IN:加入聊天(通知其他用户本人已经加入聊天室服务器) LIST:列出所有的用户(向客户端发送全部的登录用户名字) CHAT:发送聊天信息(公开的聊天信息) PRIV:进行私聊(三个参数:私聊信息用户;接收私聊信息用户;发送信息) EXIT:客户端向服务器发送离开请求; QUIT:退出聊天,服务器向客户端发送退出命令(执行QUIT命令聊天状态变为CLOSED) 四、系统实现 服务器协议解析: 当有客户端连接聊天室服务器后,服务器立刻为这个客户建立一个数据接收的线程(多用户程序必备)。在接收线程中,如果收到聊天命令,就对其进行解析处理,服务器可以处理五种命令:CONN\L

5、IST\CHAT\PRIV\EXIT。 服务器接收到CONN命令,就向其他用户发送JOIN命令告诉有用户加入,然后把当前的全部用户信息返回给刚刚加入的用户,以便在界面上显示用户列表。当接收到EXIT命令后,就清除当前用户的信息,然后向其他用户发送QUIT命令,告诉其他用户退出了,这些用户的客户端把离开的用户从用户列表中删除。 聊天室客户端的协议解析: 当客户端连接到服务器后,服务器立刻建立一个数据接收的独立线程。在接收线程中,如果收到了聊天命令,就对其进行解析处理。聊天室客户端一共处理的命令有五种:OK\ERR\LIST\JOIN\QUIT命令。 五、程序设计(代码)

6、服务器端设计: 引入网络操作命名空间System.Net、System.Net.Sockets; 线程处理命名空间System.Threading 第一步:界面设计及类与相关成员的定义 对界面进行设计(简单) 对内部函数进行设计(要编写一个独立的类即Client类,封装了客户端的信息与连接,每一个客户进入聊天室,就创建一个Client对象,用于保存该用户的信息并接收用户数据和发送信息到客户端) 几个重要的类:TcpListener类(服务器套接字创建)、Socket类 internal static Hashtable clients = new Hashtable(

7、);//clients数组保存当前在线用户的client对象 private TcpListener listener;//该服务器默认的监听端口号 static int MAX_NUM = 100; //服务器可以支持的客户端的最大连接数 internal static bool SocketServiceFlag = false;//开始服务的标志 //获得本地局域网或者拨号动态分配的IP地址,在启动服务器时会用到IP地址 private string getIPAddress() {

8、 //获得本机局域网IP地址 IPAddress[] Addresslist=Dns.GetHostEntry(Dns.GetHostName()).AddressList; if (Addresslist.Length<1) { return ""; } return Addresslist[0].ToString(); }

9、//获得动态的IP地址 private static string getDynamicIPAddress() { IPAddress[] Addresslist = Dns.GetHostEntry(Dns.GetHostName()).AddressList; if (Addresslist.Length < 2) { return ""; } return Addresslist[1].To

10、String(); } //服务器监听的端口号通过getValidPort()函数获得 private int getValidPort(string port) { int lport; //测试端口号是否有效 try { //是否为空 if (port == "") { throw new

11、ArgumentException("端口号为空,不能启动服务器"); } lport = System.Convert.ToInt32(port); } catch (Exception e) { Console.WriteLine("无效的端口号:" + e.ToString()); this.rtbSocketMsg.AppendText("无效的端口号:" + e.ToStr

12、ing() + "\n"); return -1; } return lport; } private void btnSocketStart_Click(object sender, EventArgs e) { int port = getValidPort(tbSocketPort.Text); if (port < 0) { retu

13、rn; } string ip = this.getIPAddress(); try { IPAddress ipAdd = IPAddress.Parse(ip); listener = new TcpListener(ipAdd, port);//创建服务器套接字 listener.Start(); //开始监听服务器端口 this.rtbSocketM

14、sg.AppendText("Socket服务器已经启动,正在监听" + ip + "端口号:" + this.tbSocketPort.Text + "\n"); //启动一个新的线程,执行方法this.StartSocketListen, //以便在一个独立的进程中执行确认与客户端Socket连接的操作 Form1.SocketServiceFlag = true; Thread thread = new Thr

15、ead(new ThreadStart(this.StartSocketListen)); thread.Start(); this.btnSocketStart.Enabled = false; this.btnSocketStop.Enabled = true; } catch (Exception ex) { this.rtbSocketMsg.AppendText(ex.Me

16、ssage.ToString() + "\n"); } } //在新的线程中的操作,它主要用于当接收到一个客户端请求时,确认与客户端的链接 //并且立刻启动一个新的线程来处理和该客户端的信息交互 private void StartSocketListen() { while (Form1.SocketServiceFlag) { try {

17、 //当接收到一个客户端请求时,确认与客户端的链接 if (listener.Pending())//确认是否有挂起的连接请求 { Socket socket = listener.AcceptSocket();//接收挂起的连接请求 if (clients.Count >= MAX_NUM) {

18、 this.rtbSocketMsg.AppendText("已经达到了最大连接数:" + MAX_NUM + ",拒绝新的链接\n"); socket.Close(); } else { //启动一个新的线程 //执行方法this.ServiceClient,处

19、理用户相应的请求 ChatSever.Client.Client client = new ChatSever.Client.Client(this, socket); Thread clientService = new Thread(new ThreadStart(client.ServiceClient)); clientService.Start(); } }

20、 Thread.Sleep(200);//提高性能整体速度,原因不详 } catch (Exception ex) { this.rtbSocketMsg.AppendText(ex.Message.ToString() + "\n"); } } } private void tbSocketPort_

21、TextChanged(object sender, EventArgs e) { if (this.tbSocketPort.Text!="") { this.btnSocketStart.Enabled = true; } } //下面为一些界面处理函数 private void btnSocketStop_Click(object sender, EventArgs e) {

22、 Form1.SocketServiceFlag = false; this.btnSocketStart.Enabled = true; this.btnSocketStop.Enabled = false; } public void addUser(string username) { this.rtbSocketMsg.AppendText(username + "已经加入\n");//将刚连接的用户名加入到当前在线用户列表中

23、 this.lbSocketClients.Items.Add(username); this.tbSocketClientsNum.Text = System.Convert.ToString(clients.Count); } public void removeUser(string username) { this.rtbSocketMsg.AppendText(username + "已经离开\n");//将刚连接的用户名加入到当前在线用

24、户列表中 this.lbSocketClients.Items.Remove(username); this.tbSocketClientsNum.Text = System.Convert.ToString(clients.Count); } public string GetUserList() { string Rtn = ""; for (int i = 0; i < lbSocketClients.Items.Count; i+

25、) { Rtn += lbSocketClients.Items[i].ToString() + "|"; } return Rtn; } public void updateUI(string msg) { this.rtbSocketMsg.AppendText(msg + "\n"); } private void Form1_FormClosing(objec

26、t sender, FormClosingEventArgs e) { Form1.SocketServiceFlag = false; } //下面为Client类定义 public class Client { private string name;//保存用户名 private Socket currentSocket = null;//保存与当前用户连接的Socket对象 private string ipAddress;//保存用

27、户的IP地址 private Form1 server; //保存当前连接状态 //Closed--connected--closed private string state = "closed"; public Client(Form1 server, Socket clientSocket) { this.server = server; this.currentSocket = clientSocket;

28、 ipAddress = getRemoteIPAddress(); } public string Name { get { return name; } set { name = value; } } public Socket CurrentSocket {

29、 get { return currentSocket;//ipAddress } } private string getRemoteIPAddress() { return ((IPEndPoint)currentSocket.RemoteEndPoint).Address.ToString(); } //SendToClient()方法实现了向客户端发送命令请求的功

30、能 private void SendToClient(Client client, string msg) { System.Byte[] message = System.Text.Encoding.Default.GetBytes(msg.ToCharArray()); client.currentSocket.Send(message, message.Length, 0); } //ServiceClient 方法用于和客户

31、端进行数据通信,包括接收客户端的请求 //它根据不同的请求命令执行相应的操作,并将处理结果返回到客户端 //ServiceClient()函数为服务器接收客户数据的线程主体,主要用来接收用户发送来的数据,并处理聊天命令 public void ServiceClient() { string[] tokens=null; byte[] buff=new byte[1024]; bool keepCo

32、nnect=true; //用循环来不断地与客户端进行交互,直到客户端发出“EXIT”命令 //将keepConnect职为false,退出循环,关闭连接,并中止当前线程 while(keepConnect&&Form1.SocketServiceFlag) { //tokens=null; try {

33、 if(currentSocket==null||currentSocket.Available<1) { Thread.Sleep(300); continue; } //接收数据并存入BUFF数组中 int len = currentSocket.Receive(

34、buff); //将字符数组转化为字符串 string clientCommand=System.Text.Encoding.Default.GetString(buff,0,len); //tokens【0】中保存了命令标志符(CONN CHAT PRIV LIST 或 EXIT) tokens=clientCommand.Split(new char[]{'|'}); if (toke

35、ns==null) { Thread.Sleep(200); continue; } } catch(Exception e) { server.updateUI("发送异常:"+e.ToString());

36、 } } //以上代码主要用于服务器初始化和接收客户端发送来的数据。它在对用户数据进行解析后,把用户命令转换为数组方式。 if(tokens[0]=="CONN") { //此时接收到的命令格式化为命令标识符CONN|发送者的用户名|tokens[1]中保存了发送者的用户名 this.name=tokens[1]; if(Fo

37、rm1.clients.Contains(this.name)) { SendToClient(this,"ERR|User"+this.name+"已经存在"); } else { Hashtable syncClients=Hashtable.Synchronized(Form1.clients);

38、 syncClients.Add(this.name,this); //更新界面 server.addUser(this.name); //对每一个当前在线的用户发送JOIN消息命令和LIST消息命令,以此来跟新客户端的当前在线用户列表 System.Collections.IEnumerator myEnumerator=Form1.clients.Values.GetEn

39、umerator(); while(myEnumerator.MoveNext()) { Client client =(Client)myEnumerator.Current; SendToClient(client,"JOIN|"+tokens[1]+"|"); Thread.Sleep(100);

40、 } //更新状态 state ="connected"; SendToClient(this,"OK"); //向客户端发送LIST命令,以此更新客户端的当前在线用户列表 string msgUsers="LIST|"+server.GetUserList(); Sen

41、dToClient(this ,msgUsers); } } else if (tokens[0]=="CHAT") { if (state =="connected") { //此时收到的命令的格式为:命令标识符CHAT|发送者的用户名:发送内容|向所有当前在线的用户转发此信息

42、 System.Collections.IEnumerator myEnumerator=Form1.clients.Values.GetEnumerator(); while(myEnumerator.MoveNext()) { Client client =(Client)myEnumerator.Current; //将发送者的用户名:发送内容 转发给用户

43、 SendToClient(client,tokens[1]); } server.updateUI(tokens[1]); } else { //send err to server SendToClient(this,"E

44、RR|state error,please login first"); } } else if (tokens[0]=="PRIV") { if (state =="connected") { //此时收到的命令的格式为:命令标识符PRIV|发送者的用户名:发送内容|

45、//tokens[1]中保存了发生者的用户名 string sender=tokens[1]; //tokens[2]中保存了发送者的用户名 string receiver=tokens[2]; //tokens[3]中保存了发送的内容 string content =tokens[3]; st

46、ring message=sender+"-->"+receiver+”:”+content; //仅将信息转发给法送者和接收者 if (Form1.clients.Contains(sender)) { SendToClient((Client)Form1.clients[sender],message); }

47、 if (Form1.clients.Contains(receiver)) { SendToClient((Client)Form1.clients[receiver],message); } server.updateUI(tokens[1]); } else

48、 { //send err to server SendToClient(this,"ERR|state error,please login first"); } } else if (tokens[0]=="EXIT") { //此时收到的命令的格式为:命令标识符EXIT|发送者的用户名:发送内容|

49、 //向所有当前在线的用户发送该用户已离开的消息 if(Form1.clients.Contains(tokens[1])) { Client client=(Client)Form1.clients(tokens[1])); //将该用户对应Client对象从clients中删除 Hasht

50、able syncClients=Hashtable.Synchronized(Form1.clients); syncClients.Remove(client.name); server.removeUser(client.name); //向客户端发送QUIT命令 string message ="QUIT|"+tokens[1];

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2026 宁波自信网络信息技术有限公司  版权所有

客服电话:0574-28810668  投诉电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服