基于Socket的聊天室(C#版)_第1页
基于Socket的聊天室(C#版)_第2页
基于Socket的聊天室(C#版)_第3页
基于Socket的聊天室(C#版)_第4页
基于Socket的聊天室(C#版)_第5页
免费预览已结束,剩余20页可下载查看

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

一 服务器 客户端聊天室模型 聊天室客户端 商用PC 服务器 聊天室客户端 其他 聊天室客户端 笔记 本 其他服务器 1 首先启动聊天室服务器 使得 TcpListener 开始监听端口 此时 TcpListener 会进入 Pending 状态 等待客户端连接 2 其次 当有客户端连接后 通过 AccepSocket 返回与客户端连接的 Socket 对 象 然后通过读写 Socket 对象完成与聊天室客户端的数据传输 聊天室客户端 成功启动后 首先创建一个 Socket 对象 然后通过这个 Socket 对象连接聊天 室服务器 连接成功后开通 Socket 完成数据的接收和发送处理 二 系统功能设计 本设计为一个简单的聊天室工具 设计基本的聊天功能 如聊天 列表维护等 系统主要为两大块 聊天室服务器及聊天室客户端 服务器界面设计如下 客户端界面设计如下 三 聊天协议的应答 A 网络 B 主机与主机通信主要识别身份 标识设备用 IP 及通信协议 网络应用程序 端口号 接收数据 注 1 IP 地址是总机 端口号是分机 传输层 2 端口号为 16 位二进制数 范围 0 到 65535 但实际编程只能用 1024 以上 端口号 Socket 编程 首先 我们了解常用网络编程协议 我们用得最多的协议是 UDP 和 TCP UDP 是 不可靠传输服务 TCP 是可靠传输服务 UDP 就像点对点的数据传输一样 发送 者把数据打包 包上有收信者的地址和其他必要信息 至于收信者能不能收到 UDP 协议并不保证 而 TCP 协议就像 实际他们是一个层次的网络协议 是建立 在 UDP 的基础上 加入了校验和重传等复杂的机制来保证数据可靠的传达到收 信者 一个是面向连接一个无连接 各有用处 在一些数据传输率高的场合如 视频会议倾向于 UDP 而对一些数据安全要求高的地方如下载文件就倾向于 TCP Socket 网络应用程序 电话机 访问通信协议 聊天协议的应答 客户端服务器 聊天命令 OK ERR应答信号 聊天状态 CLOSED 和 CONNECTED 状态 执行 CONN 命令后进入 CONNECTED 状态 执行下列命令 CONN 连接聊天室服务器 JOIN 加入聊天 通知其他用户本人已经加入聊天室服务器 LIST 列出所有的用户 向客户端发送全部的登录用户名字 CHAT 发送聊天信息 公开的聊天信息 PRIV 进行私聊 三个参数 私聊信息用户 接收私聊信息用户 发送信息 EXIT 客户端向服务器发送离开请求 QUIT 退出聊天 服务器向客户端发送退出命令 执行 QUIT 命令聊天状态变为 CLOSED 四 系统实现 服务器协议解析 当有客户端连接聊天室服务器后 服务器立刻为这个客户建立一个数据接 收的线程 多用户程序必备 在接收线程中 如果收到聊天命令 就对其进行 解析处理 服务器可以处理五种命令 CONN LIST CHAT PRIV EXIT 服务器接收到 CONN 命令 就向其他用户发送 JOIN 命令告诉有用户加入 然后把当前的全部用户信息返回给刚刚加入的用户 以便在界面上显示用户列 表 当接收到 EXIT 命令后 就清除当前用户的信息 然后向其他用户发送 QUIT 命令 告诉其他用户退出了 这些用户的客户端把离开的用户从用户列表 中删除 启动聊天服务器 启动监听器 等待 接收客户端连接 启动客户数据接收线程 保持连接并且SocketServiceFlag为true 退出线程 读取数据 解析命令 CONN命令CHAT命令LIST命令EXIT命令PRIV命令 向全部用户发 送JOIN命令 向当用户发送 LIST命令 向当用户发送 LIST命令 向当用户发送 CHAT命令 向接收者发送 数据 向发送者发送 数据 向全部用户发 送QUIT命令 删除用户数据 休息200毫秒 聊天室客户端的协议解析 当客户端连接到服务器后 服务器立刻建立一个数据接收的独立线程 在接收 线程中 如果收到了聊天命令 就对其进行解析处理 聊天室客户端一共处理 的命令有五种 OK ERR LIST JOIN QUIT 命令 Socket Connect 启动客户数据接收线程 是停止标志吗 退出线程 读取数据 解析命令 OK命令LIST命令ERR命令 QUIT命令 JOIN命令 命令执行成功命令执行失败显示全部用户显示用户加入 显示用户离开 删除用户数据 休息200毫秒 启动聊天室客 户端 No Yes 其他情况 直接显示 用户信息 五 程序设计 代码 服务器端设计 引入网络操作命名空间 System Net System Net Sockets 线程处理命名空间 System Threading 第一步 界面设计及类与相关成员的定义 对界面进行设计 简单 对内部函数进行设计 要编写一个独立的类即 Client 类 封装了客户端的信息 与连接 每一个客户进入聊天室 就创建一个 Client 对象 用于保存该用户的 信息并接收用户数据和发送信息到客户端 几个重要的类 TcpListener 类 服务器套接字创建 Socket 类 internal static Hashtable clients new Hashtable clients数组保存当前在线用户的client对 象 private TcpListener listener 该服务器默认的监听端口号 static int MAX NUM 100 服务器可以支持的客户端的最大连接数 internal static bool SocketServiceFlag false 开始服务的标志 获得本地局域网或者拨号动态分配的IP地址 在启动服务器时会用到IP地址 private string getIPAddress 获得本机局域网IP地址 IPAddress Addresslist Dns GetHostEntry Dns GetHostName AddressList if Addresslist Length 1 return return Addresslist 0 ToString 获得动态的IP地址 private static string getDynamicIPAddress IPAddress Addresslist Dns GetHostEntry Dns GetHostName AddressList if Addresslist Length 2 return return Addresslist 1 ToString 服务器监听的端口号通过getValidPort 函数获得 private int getValidPort string port int lport 测试端口号是否有效 try 是否为空 if port throw new ArgumentException 端口号为空 不能启动服务器 lport System Convert ToInt32 port catch 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 已经达到了最大连接数 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 提高性能整体速度 原因不详 catch 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 SocketServiceFlag 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 Rtn for int i 0 i lbSocketClients Items Count i Rtn lbSocketClients Items i ToString return Rtn public void updateUI string msg this rtbSocketMsg AppendText msg n private void Form1 FormClosing object sender FormClosingEventArgs e Form1 SocketServiceFlag false 下面为 Client 类定义 public class Client private string name 保存用户名 private Socket currentSocket null 保存与当前用户连接的Socket对象 private string ipAddress 保存用户的IP地址 private Form1 server 保存当前连接状态 Closed connected closed private string state closed public Client Form1 server Socket clientSocket this server server this currentSocket clientSocket ipAddress getRemoteIPAddress public string Name get return name set name value public Socket CurrentSocket get return currentSocket ipAddress private string getRemoteIPAddress return IPEndPoint currentSocket RemoteEndPoint Address ToString SendToClient 方法实现了向客户端发送命令请求的功能 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 方法用于和客户端进行数据通信 包括接收客户端的请求 它根据不同的请求命令执行相应的操作 并将处理结果返回到客户端 ServiceClient 函数为服务器接收客户数 据的线程主体 主要用来接收用户发送来的数据 并 处理聊天命令 public void ServiceClient string tokens null byte buff new byte 1024 bool keepConnect true 用循环来不断地与客户端进行交互 直到客户端发出 EXIT 命令 将keepConnect职为false 退出循环 关闭连接 并中止当前线程 while keepConnect try if currentSocket null currentSocket Available receiver content 仅将信息转发给法送者和接收者 if Form1 clients Contains sender SendToClient Client Form1 clients sender message if Form1 clients Contains receiver SendToClient Client Form1 clients receiver message server updateUI tokens 1 else send err to server SendToClient this ERR state error please login first else if tokens 0 EXIT 此时收到的命令的格式为 命令标识符EXIT 发送者的用户名 发送内容 向所有当前在线的用户发送该用户已离开的消息 if Form1 clients Contains tokens 1 Client client Client Form1 clients tokens 1 将该用户对应Client对象从clients中删除 Hashtable syncClients Hashtable Synchronized Form1 clients syncClients Remove client name server removeUser client name 向客户端发送QUIT命令 string message QUIT tokens 1 System Collections IEnumerator myEnumerator Form1 clients Values GetEnumerator while myEnumerator MoveNext Client c Client myEnumerator Current 将发送者的用户名 发送内容 转发给用户 SendToClient c message server updateUI QUIT 退出当前线程 break Thread Sleep 200 客户端设计 包含一个类ChatClientForm 该类封装了聊天室客户端界面和聊天命令处理逻辑 其中一个重要的类TcpClient类 用于与服务器的连接 TcpClient tcpClient 与服务器的链接 private NetworkStream Stream 与服务器数据交互的流通道 private static string CLOSED closed private static string CONNECTED connected private string state CLOSED private bool stopFlag private Color color 保存当前客户端显示的颜色 连接聊天室服务器 通过TcpClient方法连接聊天室服务器并 发送CONN消息命令 private void btnLogin Click 1 object sender EventArgs e if state CONNECTED return if this tbUserName TextLength 0 MessageBox Show 请输入您的昵称 提示信息 MessageBoxButtons OK MessageBoxIcon Exclamation this tbUserName Focus 为控件设置焦点 人性化设计 return try 创建一个客户端套接字 它是Login的一个公共属性 tcpClient new TcpClient 将被传递给ChatClient窗体 tcpClient Connect IPAddress Parse txtHost Text Int32 Parse txtPort Text 向指定 的IP地址服务器发出连接请求 Stream tcpClient GetStream 获得与服务器数据交互的流通道 NetworksStream 启动一个新的线程 执行方法this ServerResponse 以便来响应从服务器发回的 信息 Thread thread1 new Thread new ThreadStart this ServerResponse thread1 Start 向服务器发送CONN请求命令 此命令的格式与服务器端的定义的格式一致 命令格式为 命令标志符CONN 发送者的用户名 string cmd CONN this tbUserName Text 将字符串转化为字符数组 Byte outbytes System Text Encoding Default GetBytes cmd ToCharArray Stream Write outbytes 0 outbytes Length catch Exception ex MessageBox Show ex Message private void btnSend Click 1 object sender EventArgs e try if this cbPrivate Checked 此时命令的格式是 命令标识符CHAT 发送者的用户名 发送内容 string message CHAT this tbUserName Text tbSendContent Text tbSendContent Text tbSendContent Focus byte outbytes System Text Encoding Default GetBytes message ToCharArray 将字符串转化为字符数组 Stream Write outbytes 0 outbytes Length else if lstUsers SelectedIndex 1 MessageBox Show 请在列表中选择一个用户 提示信息 MessageBoxButtons OK MessageBoxIcon Exclamation return string receiver lstUsers SelectedItem ToString 消息的格式是 命令标识符PRIV 发送者的用户名 接收者的用户名 发送内容 string message PRIV this tbUserName Text receiver tbSendContent Text tbSendContent Text tbSendContent Focus byte outbytes System Text Encoding Default GetBytes message ToCharArray 将字符串转化为字符数组 Stream Write outbytes 0 outbytes Length catch this rtbMsg AppendText 网络发生错误 this ServerResponse 方法用于接收从服务器发回的信息 根据不同的命令 执行相应的操 作 private void ServerResponse 定义一个byte数组 用于接收从服务器端发来的数据 每次所能接受的数据包的最大长度为1024个字节 byte buff new byte 1024 string msg int len try if Stream CanRead false return stopFlag false while stopFlag 从流中得到数据 并存入到buff字符数组中 len Stream Read buff 0 buff Length if len 1 Thread Sleep 200 continue 将字符数组转化为字符串 msg System Text Encoding Default GetString buff 0 len msg Trim string tokens msg Split new char tokens 0 中保存了命令标志符LIST JOIN QUIT if tokens 0 ToUpper OK 处理响应 add 命令执行成功 else if tokens 0 ToUpper ERR add 命令执行错误 tokens 1 else if tokens 0 LIST 此时从服务器返回的消息格式 命令标志符LIST 用户名1 用户名2 所有在线用户 名 add 获得用户列表 更新在线用户列表 lstUsers Items Clear for int i 1 i 1 this lstUsers Items Remove tokens 1 add 用户 tokens 1 已经离开 else 如果从服务器返回的其他消息格式 则在ListBox控件中直接显示 this rtbMsg SelectedText msg n add msg 关闭连接 tcpClient Close catch add 网络发生错误 设置字体颜色 向显示消息的rtbMsg中添加信息是通过add函数完成的 private void add string msg if color IsEmpty this rtbMsg SelectionColor color this rtbMsg SelectedText msg n private void btnExit Click 1 object sender EventArgs e if true string message EXIT this tbUserName Text 将字符串转化为字符数组 byte outbytes System Text Encoding Default GetBytes message ToCharArray Stream Write outbytes 0 outbytes Length this state CLOSED this stopFlag true this lstUsers Items Clear 将 EXIT 命令发送给服务器 此命令格式要与服务器端的命令格式一致 private void Form1 FormClosing object sender FormClosingEventArgs e btnExit Click 1 sender e btnExit Click 1 sender e private void btnColor Click object sender EventArgs e ColorDialog colorDialog1 new ColorDialog colorDialog1 Color this rtbMsg SelectionColor if colorDialog1 ShowDialog System Windows Forms DialogResult OK color colorDialog1 Color private void btnSend Click 1 object sender EventArgs e try if this cbPrivate Checked 此时命令的格式是 命令标识符CHAT 发送者的用户名 发送内容 string message CHAT this tbUserName Text tbSendContent Text tbSendContent Text tbSendContent Focus byte outbytes System Text Encoding Default GetBytes message ToCharArray 将字符串转化为字符数组 Stream Write outbytes 0 outbytes Length else if lstUsers SelectedIndex 1 MessageBox Show 请在列表中选择一个用户 提示信息 MessageBoxButtons OK MessageBoxIcon Exclamation return string receiver lstUsers SelectedItem ToString 消息的格式是 命令标识符PRIV 发送者的用户名 接收者的用户名 发送内容 string message PRIV this tbUserName Text receiver tbSendContent Text tbSendContent Text tbSendContent Focus byte outbytes System Text Encoding Default GetBytes message ToCharArray 将字符串转化为字符数组 Stream Write outbytes 0 outbytes Length catch this rtbMsg AppendText 网络发生错误 this ServerResponse 方法用于接收从服务器发回的信息 根据不同的命令 执行相应的操 作 private void ServerResponse 定义一个byte数组 用于接收从服务器端发来的数据 每次所能接受的数据包的最大长度为1024个字节 byte buff new byte 1024 string msg int len try if Stream CanRead false return stopFlag false while stopFlag 从流中得到数据 并存入到buff字符数组中 len Stream Read buff 0 buff Length if len 1 Thread Sleep 200 continue 将字符数组转化为字符串 msg System Text Encoding Default GetString buff 0 len msg Trim string

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论