C#Server Socket停止接受新连接

时间:2018-05-28 10:59:33

标签: c# sockets tcpserver raw-sockets

我已经根据服务器套接字和事件编写了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天,因为不明原因一个接一个地接受插座。你能解释它为什么会这样解决这个问题吗?

0 个答案:

没有答案