本文介紹
在上一篇部落格我說了,我將會介紹c#中使用Socket和TcpListener和UdpClient實作各種同步和非同步的TCP和UDP伺服器,這些都是我自己花了很多天的時間來總結的,這樣一來相信剛接觸c#網絡編程的朋友們不會像以前的我一樣到處出找資料,到處調試。這次我介紹的是使用Socket來實現的同步的TCP伺服器,同步的TCP伺服器和第一篇裡面介紹的非同步TCP伺服器的差別就是,在Socket呼叫Accept的時候是否會阻塞。
同步的TCP伺服器在接受到一個客戶端的請求的時候一般是開啟一個線程去處理和這個客戶端的通訊工作,這種方式的不好的地方就是資源消耗大,但是假如使用線程池的話,事先分配一定數量的線程,效能還是可以。
但是我之所以給出很多方法實現的伺服器,主要目的就是想測試哪種情況效能比較不錯,就目前來看,非同步的模式比較NICE,但其實還有一個IOCP模式效能是最好的。 。 。
Socket同步TCP伺服器
服務端程式碼
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net.Sockets; using System.Net; using System.Threading; namespace NetFrame.Net.TCP.Sock.Synchronous { /// <summary> /// 基于socket实现的同步TCP服务器 /// </summary> public class SocketTCPServer { #region Fields /// <summary> /// 服务器程序允许的最大客户端连接数 /// </summary> private int _maxClient; /// <summary> /// 当前的连接的客户端数 /// </summary> private int _clientCount; /// <summary> /// 服务器使用的异步socket /// </summary> private Socket _serverSock; /// <summary> /// 客户端会话列表 /// </summary> private List<SocketClientHandle> _clients; private bool disposed = false; #endregion #region Properties /// <summary> /// 服务器是否正在运行 /// </summary> public bool IsRunning { get; private set; } /// <summary> /// 监听的IP地址 /// </summary> public IPAddress Address { get; private set; } /// <summary> /// 监听的端口 /// </summary> public int Port { get; private set; } /// <summary> /// 通信使用的编码 /// </summary> public Encoding Encoding { get; set; } #endregion #region 构造函数 /// <summary> /// 同步Socket TCP服务器 /// </summary> /// <param name="listenPort">监听的端口</param> public SocketTCPServer(int listenPort) : this(IPAddress.Any, listenPort, 1024) { } /// <summary> /// 同步Socket TCP服务器 /// </summary> /// <param name="localEP">监听的终结点</param> public SocketTCPServer(IPEndPoint localEP) : this(localEP.Address, localEP.Port, 1024) { } /// <summary> /// 同步Socket TCP服务器 /// </summary> /// <param name="localIPAddress">监听的IP地址</param> /// <param name="listenPort">监听的端口</param> /// <param name="maxClient">最大客户端数量</param> public SocketTCPServer(IPAddress localIPAddress, int listenPort, int maxClient) { this.Address = localIPAddress; this.Port = listenPort; this.Encoding = Encoding.Default; _maxClient = maxClient; _clients = new List<SocketClientHandle>(); _serverSock = new Socket(localIPAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp); } #endregion #region Method /// <summary> /// 启动服务器 /// </summary> public void Start() { if (!IsRunning) { IsRunning = true; _serverSock.Bind(new IPEndPoint(this.Address, this.Port)); Thread thread = new Thread(StartListen); thread.Start(); } } /// <summary> /// 开始进行监听 /// </summary> private void StartListen() { _serverSock.Listen(1024); SocketClientHandle handle; while (IsRunning) { if (_clientCount >= _maxClient) { //TODO 客户端过多异常 RaiseOtherException(null); } else { Socket clientSock = _serverSock.Accept(); _clientCount++; //TODO 创建一个处理客户端的线程并启动 handle = new SocketClientHandle(clientSock); _clients.Add(handle); //使用线程池来操作 ThreadPool.QueueUserWorkItem(new WaitCallback(handle.RecevieData)); //Thread pthread; //pthread = new Thread(new ThreadStart(client.RecevieData)); //pthread.Start(); //这里应该使用线程池来进行 } } } /// <summary> /// 停止服务器 /// </summary> public void Stop() { if (IsRunning) { IsRunning = false; _serverSock.Close(); //TODO 关闭对所有客户端的连接 } } /// <summary> /// 发送函数 /// </summary> public void Send(string msg, SocketClientHandle client) { //TODO } /// <summary> /// 关闭一个与客户端之间的会话 /// </summary> /// <param name="handle">需要关闭的客户端会话对象</param> public void Close(SocketClientHandle handle) { if (handle != null) { _clients.Remove(handle); handle.Dispose(); _clientCount--; //TODO 触发关闭事件 } } /// <summary> /// 关闭所有的客户端会话,与所有的客户端连接会断开 /// </summary> public void CloseAllClient() { foreach (SocketClientHandle handle in _clients) { Close(handle); } _clientCount = 0; _clients.Clear(); } #endregion #region 事件 /// <summary> /// 与客户端的连接已建立事件 /// </summary> public event EventHandler<SocketEventArgs> ClientConnected; /// <summary> /// 与客户端的连接已断开事件 /// </summary> public event EventHandler<SocketEventArgs> ClientDisconnected; /// <summary> /// 触发客户端连接事件 /// </summary> /// <param name="state"></param> private void RaiseClientConnected(SocketClientHandle handle) { if (ClientConnected != null) { ClientConnected(this, new SocketEventArgs(handle)); } } /// <summary> /// 触发客户端连接断开事件 /// </summary> /// <param name="client"></param> private void RaiseClientDisconnected(Socket client) { if (ClientDisconnected != null) { ClientDisconnected(this, new SocketEventArgs("连接断开")); } } /// <summary> /// 接收到数据事件 /// </summary> public event EventHandler<SocketEventArgs> DataReceived; private void RaiseDataReceived(SocketClientHandle handle) { if (DataReceived != null) { DataReceived(this, new SocketEventArgs(handle)); } } /// <summary> /// 数据发送事件 /// </summary> public event EventHandler<SocketEventArgs> CompletedSend; /// <summary> /// 触发数据发送事件 /// </summary> /// <param name="state"></param> private void RaiseCompletedSend(SocketClientHandle handle) { if (CompletedSend != null) { CompletedSend(this, new SocketEventArgs(handle)); } } /// <summary> /// 网络错误事件 /// </summary> public event EventHandler<SocketEventArgs> NetError; /// <summary> /// 触发网络错误事件 /// </summary> /// <param name="state"></param> private void RaiseNetError(SocketClientHandle handle) { if (NetError != null) { NetError(this, new SocketEventArgs(handle)); } } /// <summary> /// 异常事件 /// </summary> public event EventHandler<SocketEventArgs> OtherException; /// <summary> /// 触发异常事件 /// </summary> /// <param name="state"></param> private void RaiseOtherException(SocketClientHandle handle, string descrip) { if (OtherException != null) { OtherException(this, new SocketEventArgs(descrip, handle)); } } private void RaiseOtherException(SocketClientHandle handle) { RaiseOtherException(handle, ""); } #endregion #region Close 未实现 #endregion #region 释放 /// <summary> /// Performs application-defined tasks associated with freeing, /// releasing, or resetting unmanaged resources. /// </summary> public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } /// <summary> /// Releases unmanaged and - optionally - managed resources /// </summary> /// <param name="disposing"><c>true</c> to release /// both managed and unmanaged resources; <c>false</c> /// to release only unmanaged resources.</param> protected virtual void Dispose(bool disposing) { if (!this.disposed) { if (disposing) { try { Stop(); if (_serverSock != null) { _serverSock = null; } } catch (SocketException) { //TODO 异常 } } disposed = true; } } #endregion } }
對用戶端操作封裝的Handle類別
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net.Sockets; namespace NetFrame.Net.TCP.Sock.Synchronous { /// <summary> /// Socket 服务器用于处理客户端连接封装的客户端处理类 /// </summary> public class SocketClientHandle:IDisposable { /// <summary> /// 与客户端相关联的socket /// </summary> private Socket _client; /// <summary> /// 标识是否与客户端相连接 /// </summary> private bool _is_connect; public bool IsConnect { get { return _is_connect; } set { _is_connect = value; } } /// <summary> /// 数据接受缓冲区 /// </summary> private byte[] _recvBuffer; public SocketClientHandle(Socket client) { this._client = client; _is_connect = true; _recvBuffer = new byte[1024 * 1024 * 2]; } #region Method /// <summary> /// 接受来自客户端发来的数据 /// </summary> public void RecevieData(Object state) { int len = -1; while (_is_connect) { try { len = _client.Receive(_recvBuffer); } catch (Exception) { //TODO } } } /// <summary> /// 向客户端发送数据 /// </summary> public void SendData(string msg) { byte[] data = Encoding.Default.GetBytes(msg); try { //有一种比较好的写法 _client.Send(data); } catch (Exception) { //TODO 处理异常 } } #endregion #region 事件 //TODO 消息发送事件 //TODO 数据收到事件 //TODO 异常处理事件 #endregion #region 释放 /// <summary> /// Performs application-defined tasks associated with freeing, /// releasing, or resetting unmanaged resources. /// </summary> public void Dispose() { _is_connect = false; if (_client != null) { _client.Close(); _client = null; } GC.SuppressFinalize(this); } #endregion } }
# Socket同步TCP伺服器的時間參數類別
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace NetFrame.Net.TCP.Sock.Synchronous { /// <summary> /// 同步Socket TCP服务器事件类 /// </summary> public class SocketEventArgs : EventArgs { /// <summary> /// 提示信息 /// </summary> public string _msg; /// <summary> /// 客户端状态封装类 /// </summary> public SocketClientHandle _handle; /// <summary> /// 是否已经处理过了 /// </summary> public bool IsHandled { get; set; } public SocketEventArgs(string msg) { this._msg = msg; IsHandled = false; } public SocketEventArgs(SocketClientHandle handle) { this._handle = handle; IsHandled = false; } public SocketEventArgs(string msg, SocketClientHandle handle) { this._msg = msg; this._handle = handle; IsHandled = false; } } }
以上就是C#網路程式設計系列文章(二)之Socket實作同步TCP伺服器的內容,更多相關內容請關注PHP中文網(www.php.cn) !

如何使用C#编写时间序列预测算法时间序列预测是一种通过分析过去的数据来预测未来数据趋势的方法。它在很多领域,如金融、销售和天气预报中有广泛的应用。在本文中,我们将介绍如何使用C#编写时间序列预测算法,并附上具体的代码示例。数据准备在进行时间序列预测之前,首先需要准备好数据。一般来说,时间序列数据应该具有足够的长度,并且是按照时间顺序排列的。你可以从数据库或者

如何使用Redis和C#开发分布式事务功能引言分布式系统的开发中,事务处理是一项非常重要的功能。事务处理能够保证在分布式系统中的一系列操作要么全部成功,要么全部回滚。Redis是一种高性能的键值存储数据库,而C#是一种广泛应用于开发分布式系统的编程语言。本文将介绍如何使用Redis和C#来实现分布式事务功能,并提供具体代码示例。I.Redis事务Redis

如何实现C#中的人脸识别算法人脸识别算法是计算机视觉领域中的一个重要研究方向,它可以用于识别和验证人脸,广泛应用于安全监控、人脸支付、人脸解锁等领域。在本文中,我们将介绍如何使用C#来实现人脸识别算法,并提供具体的代码示例。实现人脸识别算法的第一步是获取图像数据。在C#中,我们可以使用EmguCV库(OpenCV的C#封装)来处理图像。首先,我们需要在项目

如何使用C#编写动态规划算法摘要:动态规划是求解最优化问题的一种常用算法,适用于多种场景。本文将介绍如何使用C#编写动态规划算法,并提供具体的代码示例。一、什么是动态规划算法动态规划(DynamicProgramming,简称DP)是一种用来求解具有重叠子问题和最优子结构性质的问题的算法思想。动态规划将问题分解成若干个子问题来求解,通过记录每个子问题的解,

Redis在C#开发中的应用:如何实现高效的缓存更新引言:在Web开发中,缓存是提高系统性能的常用手段之一。而Redis作为一款高性能的Key-Value存储系统,能够提供快速的缓存操作,为我们的应用带来了不少便利。本文将介绍如何在C#开发中使用Redis,实现高效的缓存更新。Redis的安装与配置在开始之前,我们需要先安装Redis并进行相应的配置。你可以

C#开发中如何处理跨域请求和安全性问题在现代的网络应用开发中,跨域请求和安全性问题是开发人员经常面临的挑战。为了提供更好的用户体验和功能,应用程序经常需要与其他域或服务器进行交互。然而,浏览器的同源策略导致了这些跨域请求被阻止,因此需要采取一些措施来处理跨域请求。同时,为了保证数据的安全性,开发人员还需要考虑一些安全性问题。本文将探讨C#开发中如何处理跨域请

如何实现C#中的图像压缩算法摘要:图像压缩是图像处理领域中的一个重要研究方向,本文将介绍在C#中实现图像压缩的算法,并给出相应的代码示例。引言:随着数字图像的广泛应用,图像压缩成为了图像处理中的重要环节。压缩能够减小存储空间和传输带宽,并能提高图像处理的效率。在C#语言中,我们可以通过使用各种图像压缩算法来实现对图像的压缩。本文将介绍两种常见的图像压缩算法:

如何在C#中实现遗传算法引言:遗传算法是一种模拟自然选择和基因遗传机制的优化算法,其主要思想是通过模拟生物进化的过程来搜索最优解。在计算机科学领域,遗传算法被广泛应用于优化问题的解决,例如机器学习、参数优化、组合优化等。本文将介绍如何在C#中实现遗传算法,并提供具体的代码示例。一、遗传算法的基本原理遗传算法通过使用编码表示解空间中的候选解,并利用选择、交叉和


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

Dreamweaver CS6
視覺化網頁開發工具

禪工作室 13.0.1
強大的PHP整合開發環境

SAP NetWeaver Server Adapter for Eclipse
將Eclipse與SAP NetWeaver應用伺服器整合。

mPDF
mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

Atom編輯器mac版下載
最受歡迎的的開源編輯器