本文主要是介绍C#网络编程系列文章(四)之TcpListener实现同步TCP服务器,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
原创性声明
本文作者:小竹zz 本文地址http://blog.csdn.net/zhujunxxxxx/article/details/44258719 转载请注明出处
文章系列目录
C#网络编程系列文章(一)之Socket实现异步TCP服务器
C#网络编程系列文章(二)之Socket实现同步TCP服务器
C#网络编程系列文章(三)之TcpListener实现异步TCP服务器
C#网络编程系列文章(四)之TcpListener实现同步TCP服务器
C#网络编程系列文章(五)之Socket实现异步UDP服务器
C#网络编程系列文章(六)之Socket实现同步UDP服务器
C#网络编程系列文章(七)之UdpClient实现异步UDP服务器
C#网络编程系列文章(八)之UdpClient实现同步UDP服务器
本文介绍
TcpListener 类提供一些简单方法,用于在阻止同步模式下侦听和接受传入连接请求。 可使用 TcpClient 或 Socket 来连接 TcpListener。 可使用 IPEndPoint、本地 IP 地址及端口号或者仅使用端口号,来创建 TcpListener。 可以将本地 IP 地址指定为 Any,将本地端口号指定为 0(如果希望基础服务提供程序为您分配这些值)。 如果您选择这样做,可在连接套接字后使用 LocalEndpoint 属性来标识已指定的信息。使用 Start 方法,可开始侦听传入的连接请求。 Start 将对传入连接进行排队,直至您调用 Stop 方法或它已经完成 MaxConnections 排队为止。 可使用 AcceptSocket 或 AcceptTcpClient 从传入连接请求队列提取连接。 这两种方法将阻止。 如果要避免阻止,可首先使用 Pending 方法来确定队列中是否有可用的连接请求。虽然TcpListener已经封装的比较不错了,我们于是就使用它在构造一个比较不错的同步TCP服务器,这里依然和前两章一样,给出服务器中的代码,代码中注释很详细,我也会给出相关的封装类。
TcpListener同步TCP服务器
[csharp] view plain copy
- 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
- }
- }
[csharp] view plain copy
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Net.Sockets;
- using System.IO;
- namespace NetFrame.Net.TCP.Listener.Synchronous
- {
- /// <summary>
- /// TcpListener实现同步TCP服务器 的客户端连接处理类
- /// </summary>
- public class TCPClientHandle
- {
- private TcpClient _tcpclient;
- private BinaryReader rs;
- private BinaryWriter ws;
- /// <summary>
- /// 标识是否与客户端相连接
- /// </summary>
- private bool _is_connect;
- public bool IsConnect
- {
- get { return _is_connect; }
- set { _is_connect = value; }
- }
- /// <summary>
- /// 数据接受缓冲区
- /// </summary>
- private byte[] _recvBuffer;
- public TCPClientHandle(TcpClient client)
- {
- _tcpclient = client;
- rs = new BinaryReader(client.GetStream());
- ws = new BinaryWriter(client.GetStream());
- // NetworkStream ns = tmpTcpClient.GetStream();
- // if(ns.CanRead&&ns.CanWrite)
- _recvBuffer=new byte[client.ReceiveBufferSize];
- }
- /// <summary>
- /// 接受数据
- /// </summary>
- public void RecevieData()
- {
- int len = 0;
- while (_is_connect)
- {
- try
- {
- len = rs.Read(_recvBuffer, 0, _recvBuffer.Length);
- }
- catch (Exception)
- {
- break;
- }
- if (len == 0)
- {
- //the client has disconnected from server
- break;
- }
- //TODO 处理收到的数据
- }
- }
- /// <summary>
- /// 向客户端发送数据
- /// </summary>
- /// <param name="msg"></param>
- public void SendData(string msg)
- {
- byte[] data = Encoding.Default.GetBytes(msg);
- try
- {
- ws.Write(data, 0, data.Length);
- ws.Flush();
- }
- catch (Exception)
- {
- //TODO 处理异常
- }
- }
- #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 (_tcpclient != null)
- {
- _tcpclient.Close();
- _tcpclient = null;
- }
- GC.SuppressFinalize(this);
- }
- #endregion
- }
- }
Tcp服务器事件参数类
[csharp] view plain copy
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- namespace NetFrame.Net.TCP.Listener.Synchronous
- {
- /// <summary>
- /// 同步TcpListener TCP服务器事件类
- /// </summary>
- public class TCPEventArgs : EventArgs
- {
- /// <summary>
- /// 提示信息
- /// </summary>
- public string _msg;
- /// <summary>
- /// 客户端状态封装类
- /// </summary>
- public TCPClientHandle _handle;
- /// <summary>
- /// 是否已经处理过了
- /// </summary>
- public bool IsHandled { get; set; }
- public TCPEventArgs(string msg)
- {
- this._msg = msg;
- IsHandled = false;
- }
- public TCPEventArgs(TCPClientHandle handle)
- {
- this._handle = handle;
- IsHandled = false;
- }
- public TCPEventArgs(string msg, TCPClientHandle handle)
- {
- this._msg = msg;
- this._handle = handle;
- IsHandled = false;
- }
- }
- }
这篇关于C#网络编程系列文章(四)之TcpListener实现同步TCP服务器的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!