C#网络编程系列文章(四)之TcpListener实现同步TCP服务器
2017-12-13 10:00
567 查看
原创性声明
本文作者:小竹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] viewplain 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服务器
- C#网络编程系列文章(三)之TcpListener实现异步TCP服务器
- C#网络编程系列文章(六)之Socket实现同步UDP服务器
- C#网络编程系列文章(一)之Socket实现异步TCP服务器
- C#网络编程系列文章(二)之Socket实现同步TCP服务器
- C#网络编程系列文章(三)之TcpListener实现异步TCP服务器
- C#网络编程系列文章(二)之Socket实现同步TCP服务器
- C#网络编程系列文章(六)之Socket实现同步UDP服务器
- C#网络编程系列文章(一)之Socket实现异步TCP服务器
- C#网络编程系列文章(七)之UdpClient实现异步UDP服务器
- C#网络编程系列文章(八)之UdpClient实现同步UDP服务器
- C#网络编程系列文章(一)之Socket实现异步TCP服务器
- C#网络编程系列文章(八)之UdpClient实现同步UDP服务器
- C#网络编程系列文章(一)之Socket实现异步TCP服务器
- Nginx网络epoll多进程系列:tcp服务器仿nginx多进程和多路IO的实现
- C#网络编程系列文章(五)之Socket实现异步UDP服务器
- C#网络编程系列文章(五)之Socket实现异步UDP服务器
- C#网络编程系列文章(七)之UdpClient实现异步UDP服务器
- 实现一个同步的迭代型TCP服务器
- 2.3 TcpListener同步基础服务器开发