实现功能,记录客户端连接个数,客户端连接的地址和端口号,能够判断哪一个客户端是否断开。
创建几个委托,可以使用Socket客户端列表,可以使用Socket和Handle记录,还可以直接记录IPEndPoint记录,或者更直接一点,使用IP地址和端口号记录客户端。
public delegate void ReceiveBuffer(byte[] buffer);
public delegate void ReceiveClientBuffer(byte[] buffer, string ClientID);
public delegate void RemoveClient(string ClientID);
public delegate void ReceiveClient(Socket socket, string ClientID);
public delegate void HostDisconnectionEvent(string IPAddress, int Port);//主机断开连接事件
不多说了,直接上代码,如果有不懂的,欢迎问我:
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
namespace System.Net.Securate.TCP
{
/// <summary>
/// TCP服务端
/// </summary>
public class TCPServer
{
private bool _IsStart = false;
/// <summary>
/// 获取当前服务是否启动
/// </summary>
public bool IsStart
{
get { return _IsStart; }
}
private TcpListener tcpServer;
private string _Address = "0.0.0.0";
/// <summary>
/// 获取或设置当前的连接地址
/// </summary>
public string Address
{
get { return _Address; }
set { _Address = value; }
}
private int _Port = 0;
/// <summary>
/// 获取或设置当前的连接端口号
/// </summary>
public int Port
{
get { return _Port; }
set { _Port = value; }
}
private int _Count;
/// <summary>
/// 获取或设置连接的客户端个数
/// </summary>
public int Count
{
get { _Count = _TCPClients.Count; return _Count; }
set { _Count = value; }
}
private List<Socket> _TCPClients = new List<Socket>();
/// <summary>
/// 获取连接的客户端
/// </summary>
public List<Socket> TCPClients
{
get { return _TCPClients; }
}
private int _ListenerCount = 2000;
/// <summary>
/// 获取或设置允许的最大连接数(默认为2000)
/// </summary>
public int ListenerCount
{
get { return _ListenerCount; }
set { _ListenerCount = value; }
}
/// <summary>
/// 收到数据时发生的事件
/// </summary>
public event ReceiveBuffer ReceiveComTemplate;
/// <summary>
/// 收到客户端数据时发生
/// </summary>
public event ReceiveClientBuffer ReceiveClientComTemplate;
/// <summary>
/// 接收到客户端连接事件
/// </summary>
public event ReceiveClient ReceiveClientComtemplate;
/// <summary>
/// 移除客户端事件
/// </summary>
public event RemoveClient RemoveClientComTemplate;
/// <summary>
/// 本机所有IP地址
/// </summary>
/// <returns></returns>
public IPAddress[] GetIPAddress()
{
string hostName = Dns.GetHostName();
IPHostEntry ipHoseEntry = Dns.GetHostEntry(hostName);
return ipHoseEntry.AddressList;
}
/// <summary>
/// 启动服务
/// </summary>
public void Start()
{
if (_Port == 0)
{
_IsStart = false;
throw new Exception("请设置端口号或端口号不能为空");
}
IPAddress ipaddress = IPAddress.Parse(_Address);
tcpServer = new TcpListener(ipaddress, _Port);
tcpServer.Start(_ListenerCount);
tcpServer.BeginAcceptSocket(new AsyncCallback(TcpAccept), tcpServer);
_IsStart = true;
}
/// <summary>
/// 接收客户端连接
/// </summary>
/// <param name="ia"></param>
private void TcpAccept(IAsyncResult ia)
{
TcpListener server = ia.AsyncState as TcpListener;
try
{
if (_IsStart)
{
TcpReceive tcpreceive = new TcpReceive();
tcpreceive.Client = server.EndAcceptSocket(ia);
_TCPClients.Add(tcpreceive.Client);
string ClientID = tcpreceive.Client.RemoteEndPoint.ToString();
if (ReceiveClientComtemplate != null)
ReceiveClientComtemplate(tcpreceive.Client, ClientID);
Receive(tcpreceive);
server.BeginAcceptSocket(new AsyncCallback(TcpAccept), server);
}
}
catch
{
try
{
server.BeginAcceptSocket(new AsyncCallback(TcpAccept), server);
}
catch { }
}
}
/// <summary>
/// 收到消息
/// </summary>
/// <param name="tcpReceive"></param>
private void Receive(TcpReceive tcpReceive)
{
tcpReceive.Client.BeginReceive(tcpReceive.Buffer, 0, tcpReceive.Buffer.Length,
SocketFlags.None, new AsyncCallback(ReceiveCallback), tcpReceive);
}
/// <summary>
/// 读取并发送消息
/// </summary>
/// <param name="ia"></param>
private void ReceiveCallback(IAsyncResult ia)
{
if (_IsStart)
{
TcpReceive tcpReceive = ia.AsyncState as TcpReceive;
if (tcpReceive != null)
{
string ClientID = tcpReceive.Client.RemoteEndPoint.ToString();
if (!tcpReceive.Client.Connected)
{
_TCPClients.Remove(tcpReceive.Client);
if (RemoveClientComTemplate != null)
RemoveClientComTemplate.Invoke(ClientID);
return;
}
if (tcpReceive.Client.Poll(1000, SelectMode.SelectRead))
{
tcpReceive.Client.Shutdown(SocketShutdown.Both);
tcpReceive.Client.Close();
_TCPClients.Remove(tcpReceive.Client);
if (RemoveClientComTemplate != null)
RemoveClientComTemplate.Invoke(ClientID);
return;
}
if (ReceiveComTemplate != null)
{
ReceiveComTemplate.Invoke(tcpReceive.Buffer);
}
if (ReceiveClientComTemplate != null)
ReceiveClientComTemplate.Invoke(tcpReceive.Buffer, ClientID);
tcpReceive.Client.BeginReceive(tcpReceive.Buffer, 0, tcpReceive.Buffer.Length,
SocketFlags.None, new AsyncCallback(ReceiveCallback), tcpReceive);
}
}
}
/// <summary>
/// 发送消息
/// </summary>
/// <param name="tcpClient">连接的客户端</param>
/// <param name="buffer">发送的字节数据</param>
public void Send(Socket tcpClient, byte[] buffer)
{
if (tcpClient.Connected)
{
tcpClient.BeginSend(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(SendCallback), tcpClient);
}
else
{
tcpClient.Shutdown(SocketShutdown.Both);
tcpClient.Close();
_TCPClients.Remove(tcpClient);
}
}
/// <summary>
/// 发送消息
/// </summary>
/// <param name="ia"></param>
private void SendCallback(IAsyncResult ia)
{
Socket tcpClient = ia.AsyncState as Socket;
tcpClient.EndSend(ia);
}
/// <summary>
/// 关闭服务
/// </summary>
public void Close()
{
tcpServer.Server.Close();
tcpServer.Stop();
for (int i = 0; i < _TCPClients.Count; i++)
{
_TCPClients[i].Shutdown(SocketShutdown.Both);
_TCPClients[i].Close();
}
_TCPClients.Clear();
_IsStart = false;
}
}
}