我已经根据服务器套接字和事件编写了TCP套接字捕获器,用于将捕获的连接转移到高级别。
public class TcpCatcher
{
private static readonly Exception IsStartedException = new Exception("Catcher has already been started.");
private int _port;
private int _openTimeout;
private Socket _serverSocket;
private SocketAsyncEventArgs _acceptAsyncArg;
public int Port
{
get => _port;
set
{
if (IsStarted)
throw IsStartedException;
_port = value;
}
}
public int OpenTimeout
{
get => _openTimeout;
set
{
if (IsStarted)
throw IsStartedException;
_openTimeout = value;
}
}
public bool IsStarted { get; protected set; }
public event Action<Socket> ConnectionCatched;
public event Action<string> Log;
public TcpCatcher()
{
_acceptAsyncArg = new SocketAsyncEventArgs();
_acceptAsyncArg.SetBuffer(null, 0, 0);
_acceptAsyncArg.Completed += OnAcceptSocket;
}
private void OnLog(string message)
{
if (Log != null)
Log(message);
}
private void AcceptSocket()
{
OnLog("AcceptSocket is executing");
bool isAsync;
do
{
isAsync = _serverSocket.AcceptAsync(_acceptAsyncArg);
if (!isAsync)
{
OnLog($"AcceptAsync finished Sync.");
if (_acceptAsyncArg.SocketError == SocketError.Success)
ConnectionCatched(_acceptAsyncArg.AcceptSocket);
}
} while (!isAsync);
OnLog("AcceptSocket finished");
}
private void OnAcceptSocket(object sender, SocketAsyncEventArgs asyncArg)
{
OnLog("Caught new socket!");
if (asyncArg.SocketError != SocketError.Success)
{
OnLog($"Socket has bad status:${asyncArg.SocketError}");
asyncArg.AcceptSocket?.Close();
}
else
{
ConnectionCatched(asyncArg.AcceptSocket);
}
OnLog($"Caught socket was processed");
asyncArg.AcceptSocket = null;
if (IsStarted)
AcceptSocket();
}
public void Start()
{
OnLog($"Starting");
IsStarted = true;
_serverSocket?.Close();
_serverSocket = new Socket(SocketType.Stream, System.Net.Sockets.ProtocolType.Tcp);
_serverSocket.Bind(new IPEndPoint(IPAddress.Any, Port));
_serverSocket.Listen((int)SocketOptionName.MaxConnections);
AcceptSocket();
}
public void Finish()
{
OnLog($"Stopping");
_serverSocket.Disconnect(false);
_serverSocket.Close();
_serverSocket.Dispose();
_serverSocket = null;
IsStarted = false;
}
}
捕获程序用于Windows服务并在服务启动时进行初始化。他们工作大约2-4天,因为不明原因一个接一个地接受插座。你能解释它为什么会这样解决这个问题吗?