1、基于Socket的聊天室C#版基于Socket的聊天室(C#版)一、服务器/客户端聊天室模型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就像点对点的数据传输一样,发送者把数据打包,包上有收信者的地址和其他必要信息,至于收信者能不能收到,UDP协议并不保证。而TCP协
3、议就像(实际他们是一个层次的网络协议)是建立在UDP的基础上,加入了校验和重传等复杂的机制来保证数据可靠的传达到收信者。一个是面向连接一个无连接,各有用处,在一些数据传输率高的场合如视频会议倾向于UDP,而对一些数据安全要求高的地方如下载文件就倾向于TCP。Socket网络应用程序电话机访问通信协议聊天协议的应答:聊天状态:CLOSED和CONNECTED状态执行CONN命令后进入CONNECTED状态,执行下列命令:CONN:连接聊天室服务器JOIN:加入聊天(通知其他用户本人已经加入聊天室服务器)LIST:列出所有的用户(向客户端发送全部的登录用户名字)CHAT:发送聊天信息(公开的聊天信
4、息)PRIV:进行私聊(三个参数:私聊信息用户;接收私聊信息用户;发送信息)EXIT:客户端向服务器发送离开请求;QUIT:退出聊天,服务器向客户端发送退出命令(执行QUIT命令聊天状态变为CLOSED)四、系统实现服务器协议解析:当有客户端连接聊天室服务器后,服务器立刻为这个客户建立一个数据接收的线程(多用户程序必备)。在接收线程中,如果收到聊天命令,就对其进行解析处理,服务器可以处理五种命令:CONNLISTCHATPRIVEXIT。 服务器接收到CONN命令,就向其他用户发送JOIN命令告诉有用户加入,然后把当前的全部用户信息返回给刚刚加入的用户,以便在界面上显示用户列表。当接收到EXI
5、T命令后,就清除当前用户的信息,然后向其他用户发送QUIT命令,告诉其他用户退出了,这些用户的客户端把离开的用户从用户列表中删除。internal static Hashtable clients = new Hashtable();/clients数组保存当前在线用户的client对象 private TcpListener listener;/该服务器默认的监听端口号 static int MAX_NUM = 100; /服务器可以支持的客户端的最大连接数 internal static bool SocketServiceFlag = false;/开始服务的标志/获得本地局域网或者拨号
6、动态分配的IP地址,在启动服务器时会用到IP地址 private string getIPAddress() /获得本机局域网IP地址 IPAddress Addresslist=Dns.GetHostEntry(Dns.GetHostName().AddressList; if (Addresslist.Length1) return ; return Addresslist0.ToString(); /获得动态的IP地址 private static string getDynamicIPAddress() IPAddress Addresslist = Dns.GetHostEntry(
7、Dns.GetHostName().AddressList; if (Addresslist.Length 2) return ; return Addresslist1.ToString(); /服务器监听的端口号通过getValidPort()函数获得 private int getValidPort(string port) int lport; /测试端口号是否有效 try /是否为空 if (port = ) throw new ArgumentException(端口号为空,不能启动服务器); lport = System.Convert.ToInt32(port); catch
8、(Exception e) Console.WriteLine(无效的端口号: + e.ToString(); this.rtbSocketMsg.AppendText(无效的端口号: + e.ToString() + n); return -1; return lport; private void btnSocketStart_Click(object sender, EventArgs e) int port = getValidPort(tbSocketPort.Text); if (port = MAX_NUM) this.rtbSocketMsg.AppendText(已经达到了最
9、大连接数: + MAX_NUM + ,拒绝新的链接n); socket.Close(); else /启动一个新的线程 /执行方法this.ServiceClient,处理用户相应的请求 ChatSever.Client.Client client = new ChatSever.Client.Client(this, socket); Thread clientService = new Thread(new ThreadStart(client.ServiceClient); clientService.Start(); Thread.Sleep(200);/提高性能整体速度,原因不详 c
10、atch (Exception ex) this.rtbSocketMsg.AppendText(ex.Message.ToString() + n); private void tbSocketPort_TextChanged(object sender, EventArgs e) if (this.tbSocketPort.Text!=) this.btnSocketStart.Enabled = true; /下面为一些界面处理函数 private void btnSocketStop_Click(object sender, EventArgs e) Form1.SocketServi
11、ceFlag = false; this.btnSocketStart.Enabled = true; this.btnSocketStop.Enabled = false; public void addUser(string username) this.rtbSocketMsg.AppendText(username + 已经加入n);/将刚连接的用户名加入到当前在线用户列表中 this.lbSocketClients.Items.Add(username); this.tbSocketClientsNum.Text = System.Convert.ToString(clients.Count); public void removeUser(string username) this.rtbSocketMsg.AppendText(username + 已经离开n);/将刚连接的用户名加入到当前在线用户列表中 this.lbSocketClients.Items.Remove(username); this.tbSocketClientsNum.Text = System.Convert.ToString(clients.Count); public string GetUserList() string
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1