C#网络编程系列文章(四)之TcpListener实现同步TCP服务器

原创性声明

本文作者:小竹zz 本文地址 转载请注明出处

本文介绍TcpListener 类提供一些简单方法,用于在阻止同步模式下侦听和接受传入连接请求。 可使用 TcpClient 或 Socket 来连接 TcpListener。 可使用 IPEndPoint、本地 IP 地址及端口号或者仅使用端口号,来创建 TcpListener。 可以将本地 IP 地址指定为 Any,将本地端口号指定为 0(如果希望基础服务提供程序为您分配这些值)。 如果您选择这样做,可在连接套接字后使用 LocalEndpoint 属性来标识已指定的信息。使用 Start 方法,可开始侦听传入的连接请求。 Start 将对传入连接进行排队,直至您调用 Stop 方法或它已经完成 MaxConnections 排队为止。 可使用 AcceptSocket 或 AcceptTcpClient 从传入连接请求队列提取连接。 这两种方法将阻止。 如果要避免阻止,可首先使用 Pending 方法来确定队列中是否有可用的连接请求。虽然TcpListener已经封装的比较不错了,,我们于是就使用它在构造一个比较不错的同步TCP服务器,这里依然和前两章一样,给出服务器中的代码,代码中注释很详细,我也会给出相关的封装类。TcpListener同步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.Listener.Synchronous{/// <summary>/// TcpListener实现同步TCP服务器/// </summary>public class TCPServer{#region Fields/// <summary>/// 服务器程序允许的最大客户端连接数/// </summary>private int _maxClient;/// <summary>/// 当前的连接的客户端数/// </summary>private int _clientCount;/// <summary>/// 服务器使用的异步TcpListener/// </summary>private TcpListener _listener;/// <summary>/// 客户端会话列表/// </summary>private List<TCPClientHandle> _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>/// 同步TCP服务器/// </summary>/// <param name="listenPort">监听的端口</param>public TCPServer(int listenPort): this(IPAddress.Any, listenPort, 1024){}/// <summary>/// 同步TCP服务器/// </summary>/// <param name="localEP">监听的终结点</param>public TCPServer(IPEndPoint localEP): this(localEP.Address, localEP.Port, 1024){}/// <summary>/// 同步TCP服务器/// </summary>/// <param name="localIPAddress">监听的IP地址</param>/// <param name="listenPort">监听的端口</param>/// <param name="maxClient">最大客户端数量</param>public TCPServer(IPAddress localIPAddress, int listenPort, int maxClient){this.Address = localIPAddress;this.Port = listenPort;this.Encoding = Encoding.Default;_maxClient = maxClient;_clients = new List<TCPClientHandle>();_listener = new TcpListener(new IPEndPoint(this.Address, this.Port));}#endregion#region Method/// <summary>/// 启动服务器/// </summary>public void Start(){if (!IsRunning){IsRunning = true;_listener.Start();Thread thread = new Thread(Accept);thread.Start();}}/// <summary>/// 开始进行监听/// </summary>private void Accept(){TCPClientHandle handle;while (IsRunning){TcpClient client = _listener.AcceptTcpClient();if (_clientCount >= _maxClient){//TODO 触发事件}else{handle = new TCPClientHandle(client);_clientCount++;_clients.Add(handle);//TODO 创建一个处理客户端的线程并启动//使用线程池来操作new Thread(new ThreadStart(handle.RecevieData)).Start();}}}/// <summary>/// 停止服务器/// </summary>public void Stop(){if (IsRunning){IsRunning = false;_listener.Stop();//TODO 关闭对所有客户端的连接}}/// <summary>/// 发送函数/// </summary>public void Send(string msg, TcpClient client){//TODO}#endregion#region 事件/// <summary>/// 与客户端的连接已建立事件/// </summary>public event EventHandler<TCPEventArgs> ClientConnected;/// <summary>/// 与客户端的连接已断开事件/// </summary>public event EventHandler<TCPEventArgs> ClientDisconnected;/// <summary>/// 触发客户端连接事件/// </summary>/// <param name="state"></param>private void RaiseClientConnected(TCPClientHandle handle){if (ClientConnected != null){ClientConnected(this, new TCPEventArgs(handle));}}/// <summary>/// 触发客户端连接断开事件/// </summary>/// <param name="client"></param>private void RaiseClientDisconnected(Socket client){if (ClientDisconnected != null){ClientDisconnected(this, new TCPEventArgs("连接断开"));}}/// <summary>/// 接收到数据事件/// </summary>public event EventHandler<TCPEventArgs> DataReceived;private void RaiseDataReceived(TCPClientHandle handle){if (DataReceived != null){DataReceived(this, new TCPEventArgs(handle));}}/// <summary>/// 数据发送事件/// </summary>public event EventHandler<TCPEventArgs> CompletedSend;/// <summary>/// 触发数据发送事件/// </summary>/// <param name="state"></param>private void RaiseCompletedSend(TCPClientHandle handle){if (CompletedSend != null){CompletedSend(this, new TCPEventArgs(handle));}}/// <summary>/// 网络错误事件/// </summary>public event EventHandler<TCPEventArgs> NetError;/// <summary>/// 触发网络错误事件/// </summary>/// <param name="state"></param>private void RaiseNetError(TCPClientHandle handle){if (NetError != null){NetError(this, new TCPEventArgs(handle));}}/// <summary>/// 异常事件/// </summary>public event EventHandler<TCPEventArgs> OtherException;/// <summary>/// 触发异常事件/// </summary>/// <param name="state"></param>private void RaiseOtherException(TCPClientHandle handle, string descrip){if (OtherException != null){OtherException(this, new TCPEventArgs(descrip, handle));}}private void RaiseOtherException(TCPClientHandle handle){RaiseOtherException(handle, "");}#endregion#region Close/// <summary>/// 关闭一个与客户端之间的会话/// </summary>/// <param name="handle">需要关闭的客户端会话对象</param>public void Close(TCPClientHandle handle){if (handle != null){_clients.Remove(handle);handle.Dispose();_clientCount–;//TODO 触发关闭事件}}/// <summary>/// 关闭所有的客户端会话,与所有的客户端连接会断开/// </summary>public void CloseAllClient(){foreach (TCPClientHandle handle in _clients){Close(handle);}_clientCount = 0;_clients.Clear();}#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 (_listener != null){_listener = null;}}catch (SocketException){//TODO 异常}}disposed = true;}}#endregion}}客户端处理封装类

地球仍然转重,世间依旧善变,而我永远爱你。

C#网络编程系列文章(四)之TcpListener实现同步TCP服务器

相关文章:

你感兴趣的文章:

标签云: