如何使用C#基于WebSocket实现聊天室功能
发表于:2025-01-17 作者:千家信息网编辑
千家信息网最后更新 2025年01月17日,这篇文章将为大家详细讲解有关如何使用C#基于WebSocket实现聊天室功能,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。ServerHelper:using Sy
千家信息网最后更新 2025年01月17日如何使用C#基于WebSocket实现聊天室功能
这篇文章将为大家详细讲解有关如何使用C#基于WebSocket实现聊天室功能,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。
ServerHelper:
using System;using System.Collections;using System.Text;using System.Security.Cryptography; namespace SocketDemo{ // Server助手 负责:1 握手 2 请求转换 3 响应转换 class ServerHelper { ////// 输出连接头信息 /// public static string ResponseHeader(string requestHeader) { Hashtable table = new Hashtable(); // 拆分成键值对,保存到哈希表 string[] rows = requestHeader.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries); foreach (string row in rows) { int splitIndex = row.IndexOf(':'); if (splitIndex > 0) { table.Add(row.Substring(0, splitIndex).Trim(), row.Substring(splitIndex + 1).Trim()); } } StringBuilder header = new StringBuilder(); header.Append("HTTP/1.1 101 Web Socket Protocol Handshake\r\n"); header.AppendFormat("Upgrade: {0}\r\n", table.ContainsKey("Upgrade") ? table["Upgrade"].ToString() : string.Empty); header.AppendFormat("Connection: {0}\r\n", table.ContainsKey("Connection") ? table["Connection"].ToString() : string.Empty); header.AppendFormat("WebSocket-Origin: {0}\r\n", table.ContainsKey("Sec-WebSocket-Origin") ? table["Sec-WebSocket-Origin"].ToString() : string.Empty); header.AppendFormat("WebSocket-Location: {0}\r\n", table.ContainsKey("Host") ? table["Host"].ToString() : string.Empty); string key = table.ContainsKey("Sec-WebSocket-Key") ? table["Sec-WebSocket-Key"].ToString() : string.Empty; string magic = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; header.AppendFormat("Sec-WebSocket-Accept: {0}\r\n", Convert.ToBase64String(SHA1.Create().ComputeHash(Encoding.ASCII.GetBytes(key + magic)))); header.Append("\r\n"); return header.ToString(); } ////// 解码请求内容 /// public static string DecodeMsg(Byte[] buffer, int len) { if (buffer[0] != 0x81 || (buffer[0] & 0x80) != 0x80 || (buffer[1] & 0x80) != 0x80) { return null; } Byte[] mask = new Byte[4]; int beginIndex = 0; int payload_len = buffer[1] & 0x7F; if (payload_len == 0x7E) { Array.Copy(buffer, 4, mask, 0, 4); payload_len = payload_len & 0x00000000; payload_len = payload_len | buffer[2]; payload_len = (payload_len << 8) | buffer[3]; beginIndex = 8; } else if (payload_len != 0x7F) { Array.Copy(buffer, 2, mask, 0, 4); beginIndex = 6; } for (int i = 0; i < payload_len; i++) { buffer[i + beginIndex] = (byte)(buffer[i + beginIndex] ^ mask[i % 4]); } return Encoding.UTF8.GetString(buffer, beginIndex, payload_len); } ////// 编码响应内容 /// public static byte[] EncodeMsg(string content) { byte[] bts = null; byte[] temp = Encoding.UTF8.GetBytes(content); if (temp.Length < 126) { bts = new byte[temp.Length + 2]; bts[0] = 0x81; bts[1] = (byte)temp.Length; Array.Copy(temp, 0, bts, 2, temp.Length); } else if (temp.Length < 0xFFFF) { bts = new byte[temp.Length + 4]; bts[0] = 0x81; bts[1] = 126; bts[2] = (byte)(temp.Length & 0xFF); bts[3] = (byte)(temp.Length >> 8 & 0xFF); Array.Copy(temp, 0, bts, 4, temp.Length); } else { byte[] st = System.Text.Encoding.UTF8.GetBytes(string.Format("暂不处理超长内容").ToCharArray()); } return bts; } }}
Server:
using System;using System.Collections.Generic;using System.Text;using System.Net;using System.Net.Sockets; namespace SocketDemo{ class ClientInfo { public Socket Socket { get; set; } public bool IsOpen { get; set; } public string Address { get; set; } } // 管理Client class ClientManager { static ListclientList = new List (); public static void Add(ClientInfo info) { if (!IsExist(info.Address)) { clientList.Add(info); } } public static bool IsExist(string address) { return clientList.Exists(item => string.Compare(address, item.Address, true) == 0); } public static bool IsExist(string address, bool isOpen) { return clientList.Exists(item => string.Compare(address, item.Address, true) == 0 && item.IsOpen == isOpen); } public static void Open(string address) { clientList.ForEach(item => { if (string.Compare(address, item.Address, true) == 0) { item.IsOpen = true; } }); } public static void Close(string address = null) { clientList.ForEach(item => { if (address == null || string.Compare(address, item.Address, true) == 0) { item.IsOpen = false; item.Socket.Shutdown(SocketShutdown.Both); } }); } // 发送消息到ClientList public static void SendMsgToClientList(string msg, string address = null) { clientList.ForEach(item => { if (item.IsOpen && (address == null || item.Address != address)) { SendMsgToClient(item.Socket, msg); } }); } public static void SendMsgToClient(Socket client, string msg) { byte[] bt = ServerHelper.EncodeMsg(msg); client.BeginSend(bt, 0, bt.Length, SocketFlags.None, new AsyncCallback(SendTarget), client); } private static void SendTarget(IAsyncResult res) { //Socket client = (Socket)res.AsyncState; //int size = client.EndSend(res); } } // 接收消息 class ReceiveHelper { public byte[] Bytes { get; set; } public void ReceiveTarget(IAsyncResult res) { Socket client = (Socket)res.AsyncState; int size = client.EndReceive(res); if (size > 0) { string address = client.RemoteEndPoint.ToString(); // 获取Client的IP和端口 string stringdata = null; if (ClientManager.IsExist(address, false)) // 握手 { stringdata = Encoding.UTF8.GetString(Bytes, 0, size); ClientManager.SendMsgToClient(client, ServerHelper.ResponseHeader(stringdata)); ClientManager.Open(address); } else { stringdata = ServerHelper.DecodeMsg(Bytes, size); } if (stringdata.IndexOf("exit") > -1) { ClientManager.SendMsgToClientList(address + "已从服务器断开", address); ClientManager.Close(address); Console.WriteLine(address + "已从服务器断开"); Console.WriteLine(address + " " + DateTimeOffset.Now.ToString("G")); return; } else { Console.WriteLine(stringdata); Console.WriteLine(address + " " + DateTimeOffset.Now.ToString("G")); ClientManager.SendMsgToClientList(stringdata, address); } } // 继续等待 client.BeginReceive(Bytes, 0, Bytes.Length, SocketFlags.None, new AsyncCallback(ReceiveTarget), client); } } // 监听请求 class AcceptHelper { public byte[] Bytes { get; set; } public void AcceptTarget(IAsyncResult res) { Socket server = (Socket)res.AsyncState; Socket client = server.EndAccept(res); string address = client.RemoteEndPoint.ToString(); ClientManager.Add(new ClientInfo() { Socket = client, Address = address, IsOpen = false }); ReceiveHelper rs = new ReceiveHelper() { Bytes = this.Bytes }; IAsyncResult recres = client.BeginReceive(rs.Bytes, 0, rs.Bytes.Length, SocketFlags.None, new AsyncCallback(rs.ReceiveTarget), client); // 继续监听 server.BeginAccept(new AsyncCallback(AcceptTarget), server); } } class Program { static void Main(string[] args) { Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); server.Bind(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 200)); // 绑定IP+端口 server.Listen(10); // 开始监听 Console.WriteLine("等待连接..."); AcceptHelper ca = new AcceptHelper() { Bytes = new byte[2048] }; IAsyncResult res = server.BeginAccept(new AsyncCallback(ca.AcceptTarget), server); string str = string.Empty; while (str != "exit") { str = Console.ReadLine(); Console.WriteLine("ME: " + DateTimeOffset.Now.ToString("G")); ClientManager.SendMsgToClientList(str); } ClientManager.Close(); server.Close(); } }}
Client:
关于"如何使用C#基于WebSocket实现聊天室功能"这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。
内容
篇文章
监听
功能
聊天室
C#
更多
服务器
消息
端口
服务
不错
实用
信息
助手
文章
知识
编码
哈希
连接头
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
网络技术面试常规问题
北京服务器电源价位
网络安全数字货币股
绝地求生上为啥一直服务器繁忙
行业志专辑数据库产品不支持
腾讯云服务器市场份额
青岛云灯网络技术有限公司
mysql数据库的组件
网络安全本科专业全称
乌镇互联网大会绿盟科技
地灵曲游戏关闭服务器
东城区网络技术咨询职责
苏州平江区网络技术公司地址
银河麒麟服务器操作系统中标价
ActiveMQ里的数据库
服务器游戏怎么删除
摄像头设置不到服务器
高端网络安全建设找哪家
河南省网络安全法规
路由器怎么设置虚拟服务器
锐捷宽带服务器名称怎么设置
数据库中NULL如何处理
nginx网络服务器负载均衡
军营网络安全宣传周大讨论
服务器安全狗设置备份
互联网巨头科技股
网络安全运营技术试卷答案
网络安全之远离不良信息
广州和深圳软件开发工资对比
软件开发和软件编程