以前写过一个Socket服务端程序,但在写4G模块项目的时候,遇到了一个问题,就是在服务端断开Socket客户端连接后,客户端收不到断开的状态,而且使用异步时,明明服务端停止服务了,但是客户端的连接依然还在,只不过不接收数据了,但客户端和服务端的连接照样还是在进行,所以花费了一天时间,继续研究Socket机制,写了一个服务端程序,这个程序不仅可以统计客户端数量,而且可以对收到的消息,发送的消息,断开的连接,接收的客户端做出事件,供外部访问,本来想做成COM控件,但想来没有什么用,没做,下面是代码,分享给大家,如果有更好的意见或建议,欢迎留言:
事件类:
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
namespace TcpLibrary
{
public sealed class AcceptClient
{
/// <summary>
/// 连接的客户端
/// </summary>
public Socket Client
{ get; set; }
/// <summary>
/// 连接地址
/// </summary>
public string Address
{ get; set; }
/// <summary>
/// 连接端口号
/// </summary>
public int Port
{ get; set; }
/// <summary>
/// SocketID
/// </summary>
public IntPtr ClientID
{ get; set; }
}
/// <summary>
/// 接收客户端事件
/// </summary>
public sealed class AcceptClientEventArgs : EventArgs
{
/// <summary>
/// 收到的客户端
/// </summary>
public Socket Client
{ get; set; }
/// <summary>
/// 收到的客户端
/// </summary>
public IPEndPoint EndPointRemote
{ get; set; }
/// <summary>
/// 收到的地址
/// </summary>
public IPAddress IPAddressRemote
{ get; set; }
/// <summary>
/// 收到客户端连接的端口号
/// </summary>
public int Port
{ get; set; }
}
/// <summary>
/// 收到客户端发送过来的数据
/// </summary>
public sealed class ReceivedBufferEventArgs : EventArgs
{
/// <summary>
/// 客户端来源
/// </summary>
public IPEndPoint EndPointRemote
{ get; set; }
/// <summary>
/// 来源客户端连接
/// </summary>
public Socket Client
{ get; set; }
/// <summary>
/// 收到的客户数据
/// </summary>
public byte[] Buffer
{ get; set; }
}
public sealed class HostDisconnectEventArgs : EventArgs
{
/// <summary>
/// 客户端来源
/// </summary>
public IPEndPoint EndPointRemote
{ get; set; }
/// <summary>
/// 客户端来源地址
/// </summary>
public string Address
{ get; set; }
/// <summary>
/// 客户端来源端口号
/// </summary>
public int Port
{ get; set; }
/// <summary>
/// 客户端来源句柄
/// </summary>
public IntPtr ClientID
{ get; set; }
/// <summary>
/// 来源客户端连接
/// </summary>
public Socket Client
{ get; set; }
}
}
委托类:
using System;
using System.Collections.Generic;
using System.Text;
namespace TcpLibrary
{
/// <summary>
/// 接收客户端事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public delegate void AcceptClientEvents(object sender, AcceptClientEventArgs e);
/// <summary>
/// 接收数据事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public delegate void ReceiveBufferEvents(object sender, ReceivedBufferEventArgs e);
/// <summary>
/// 断开客户端连接事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public delegate void HostDisconnectionEvents(object sender, HostDisconnectEventArgs e);
}
数据接收类:
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
namespace TcpLibrary
{
/// <summary>
/// Socket数据接收类
/// </summary>
public sealed class TcpReceive
{
private byte[] _Buffer = new byte[2048];
/// <summary>
/// 获取或设置接收的数据信息
/// </summary>
public byte[] Buffer
{
get { return _Buffer; }
set { _Buffer = value; }
}
private Socket _Client;
/// <summary>
/// 获取或设置连接的客户端
/// </summary>
public Socket Client
{
get { return _Client; }
set { _Client = value; }
}
}
}
服务端监听类:
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace TcpLibrary
{
/// <summary>
/// 监听类
/// </summary>
public sealed class TCPListener
{
public static ManualResetEvent allDone = new ManualResetEvent(false);
private Socket tcpListener;
/// <summary>
/// 收到客户端事件
/// </summary>
public event AcceptClientEvents AcceptClientEvent;
/// <summary>
/// 收到消息事件
/// </summary>
public event ReceiveBufferEvents ReceivedBufferEvent;
/// <summary>
/// 断开连接事件
/// </summary>
public event HostDisconnectionEvents DisconnectionEvent;
private List<Thread> listThread = new List<Thread>();
private List<AcceptClient> listClient = new List<AcceptClient>();
private object objClientList = new object();
/// <summary>
/// 获取连接的客户端集合
/// </summary>
public List<AcceptClient> Clients
{
get { return listClient; }
}
private int Port;
/// <summary>
/// 获取或设置接收超时时间(秒)
/// </summary>
public int? ReceiveTimeOut
{ get; set; }
/// <summary>
/// 获取或设置发送超时时间(秒)
/// </summary>
public int? SendTimeOut
{ get; set; }
public TCPListener(int Port)
{
this.Port = Port;
}
private bool IsStartListener = false;
public void Start()
{
tcpListener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
tcpListener.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
IPEndPoint point = new IPEndPoint(IPAddress.Parse("0.0.0.0"), Port);
tcpListener.Bind(point);
tcpListener.Listen(2000);
IsStartListener = true;
Thread thread = new Thread(new ThreadStart(ClientAcceptAsync));
thread.Start();
listThread.Add(thread);
}
private void ClientAcceptAsync()
{
while (IsStartListener)
{
try
{
TcpReceive receive = new TcpReceive();
receive.Client = tcpListener.Accept();
if (receive.Client.Connected)
{
//listClient.Add(receive.Client);
IPEndPoint point = receive.Client.RemoteEndPoint as IPEndPoint;
lock (objClientList)
{
AcceptClient ac = new AcceptClient();
ac.ClientID = receive.Client.Handle;
ac.Client = receive.Client;
ac.Address = point.Address.ToString();
ac.Port = point.Port;
listClient.Add(ac);
}
AcceptClientEventArgs e = new AcceptClientEventArgs();
e.Client = receive.Client;
e.EndPointRemote = point;
e.IPAddressRemote = e.EndPointRemote.Address;
e.Port = e.EndPointRemote.Port;
if (AcceptClientEvent != null)
AcceptClientEvent.Invoke(receive, e);
//receive.Client.BeginReceive(receive.Buffer, 0, receive.Buffer.Length, SocketFlags.None, new AsyncCallback(Receive), receive);
if(ReceiveTimeOut != null)
receive.Client.ReceiveTimeout = 1000 * Convert.ToInt32(ReceiveTimeOut);
if(SendTimeOut != null)
receive.Client.SendBufferSize = 1000 * Convert.ToInt32(SendTimeOut);
Thread thread = new Thread(new ParameterizedThreadStart(Receive));
thread.Start(receive);
listThread.Add(thread);
}
Thread.Sleep(100);
}
catch (Exception ex)
{
break;
}
}
}
private void RemoveClient(AcceptClient ac)
{
for (int i = 0; i < listClient.Count; i++)
{
if (listClient[i].ClientID == ac.ClientID)
{
try
{
listClient[i].Client.Shutdown(SocketShutdown.Both);
}
catch
{ }
finally
{
listClient[i].Client.Close();
}
listClient.RemoveAt(i);
break;
}
}
}
private void Receive(object sender)
{
TcpReceive receive = sender as TcpReceive;
HostDisconnectEventArgs e = new HostDisconnectEventArgs();
e.Client = receive.Client;
e.ClientID = receive.Client.Handle;
e.EndPointRemote = receive.Client.RemoteEndPoint as IPEndPoint;
e.Address = e.EndPointRemote.Address.ToString();
e.Port = e.EndPointRemote.Port;
AcceptClient ac = new AcceptClient();
ac.Client = receive.Client;
ac.Address = e.EndPointRemote.Address.ToString();
ac.Port = e.EndPointRemote.Port;
ac.ClientID = receive.Client.Handle;
while (IsStartListener)
{
try
{
if (!receive.Client.Connected)
{
e.Client = receive.Client;
if (DisconnectionEvent != null)
DisconnectionEvent.Invoke(this, e);
RemoveClient(ac);
try
{
receive.Client.Shutdown(SocketShutdown.Both);
}
catch { }
finally
{
receive.Client.Close();
}
break;
}
int byteRead = receive.Client.Receive(receive.Buffer, 0, receive.Buffer.Length, SocketFlags.None);
if (byteRead > 0)
{
ReceivedBufferEventArgs re = new ReceivedBufferEventArgs();
re.Buffer = new byte[byteRead];
Array.Copy(receive.Buffer, re.Buffer, byteRead);
re.Client = receive.Client;
IPEndPoint point = receive.Client.RemoteEndPoint as IPEndPoint;
re.EndPointRemote = point;
if (ReceivedBufferEvent != null)
ReceivedBufferEvent.Invoke(receive, re);
}
else
{
e.Client = receive.Client;
if (DisconnectionEvent != null)
DisconnectionEvent.Invoke(receive, e);
RemoveClient(ac);
try
{
receive.Client.Shutdown(SocketShutdown.Both);
}
catch { }
finally
{
receive.Client.Close();
}
break;
}
}
catch
{
try
{
receive.Client.Shutdown(SocketShutdown.Both);
}
catch { }
finally
{
receive.Client.Close();
}
RemoveClient(ac);
if (DisconnectionEvent != null)
DisconnectionEvent.Invoke(receive, e);
break;
}
}
}
public void Send(Socket Client, byte[] buffer)
{
if (!IsStartListener)
{
try
{
Client.Shutdown(SocketShutdown.Both);
}
catch { }
finally
{
Client.Close();
}
return;
}
if(Client.Connected)
Client.Send(buffer);
}
public void Stop()
{
IsStartListener = false;
try
{
//tcpListener.Shutdown(SocketShutdown.Both);
tcpListener.Close();
}
catch { }
tcpListener = null;
for (int i = 0; i < listClient.Count; i++)
{
try
{
listClient[i].Client.Shutdown(SocketShutdown.Both);
}
catch { }
finally
{
listClient[i].Client.Close();
}
}
for (int i = 0; i < listThread.Count; i++)
{
try
{
listThread[i].Abort();
//while (!(listThread[i].ThreadState == ThreadState.Aborted) && !(listThread[i].ThreadState == ThreadState.Stopped))
//{
// Thread thread = listThread[i];
// thread.Abort();
// if (thread.ThreadState == ThreadState.Aborted || thread.ThreadState == ThreadState.Stopped)
// {
// thread.Abort();
// break ;
// }
//}
}
catch { }
}
listClient.Clear();
listThread.Clear();
}
}
}
以上是全部代码,留做记忆或大家写的时候,可以做一 个参考,不用再绕圈子。