C# 无法停止异步TCP服务器Windows服务

C# 无法停止异步TCP服务器Windows服务,c#,.net,sockets,tcp,windows-services,C#,.net,Sockets,Tcp,Windows Services,我有一个TCP服务器windows服务,它是在.NET4.0中开发的,带有异步服务器套接字 它可以工作,但大约90%的时间我根本无法停止它:在Windows服务控制台中按下停止按钮后,它挂起并在大约一分钟后停止,但它的进程仍在继续,TCP通信仍在继续它挂起在_listener.Close()。要关闭通信,我唯一能做的就是重新启动Windows。可能是插座闭合的问题。我试图找出问题的根源,但就是找不到 客户端不在我的控制之下,它们是大约100个通过TCP发送数据的小工具 这是我的代码(更新) 非常

我有一个TCP服务器windows服务,它是在.NET4.0中开发的,带有异步服务器套接字

它可以工作,但大约90%的时间我根本无法停止它:在Windows服务控制台中按下停止按钮后,它挂起并在大约一分钟后停止,但它的进程仍在继续,TCP通信仍在继续它挂起在_listener.Close()。要关闭通信,我唯一能做的就是重新启动Windows。可能是插座闭合的问题。我试图找出问题的根源,但就是找不到

客户端不在我的控制之下,它们是大约100个通过TCP发送数据的小工具

这是我的代码(更新)

非常感谢,非常感谢您的建议

    public class DeviceTCPServer
{
    public readonly IPAddress IPAddress;
    public readonly int Port;
    public readonly int InputBufferSize;
    public readonly ConcurrentDictionary<Guid, StateObject> Connections;

    public event EventHandler OnStarted;
    public event EventHandler OnStopped;
    public event ServerEventHandler OnConnected;
    public event ServerEventHandler OnDisconnected;
    public event RecievedEventHandler OnRecieved;
    public event DroppedEventHandler OnDropped;
    public event ExceptionEventHandler OnException;
    public event ServerLogEventHandler ServerLog;

    private volatile bool _iAmListening;
    private Socket _listener;
    private Thread _listenerThread;
    private readonly ManualResetEvent _allDone = new ManualResetEvent(false);

    public bool Listening
    {
        get { return _iAmListening; }
    }

    public DeviceTCPServer(IPAddress ipAddress,
                         int port,
                         int inputBufferSize)
    {
        IPAddress = ipAddress;
        Port = port;
        InputBufferSize = inputBufferSize;

        Connections = new ConcurrentDictionary<Guid, StateObject>();
    }

    public void ThreadedStart()
    {
        _listenerThread = new Thread(Start)
        {
            CurrentUICulture = Thread.CurrentThread.CurrentUICulture,
            IsBackground = true
        };

        _listenerThread.Start();
    }

    private void Start()
    {
        try
        {
            var localEP = new IPEndPoint(IPAddress, Port);
            _listener = new Socket(localEP.Address.AddressFamily, SocketType.Stream, ProtocolType.Tcp);

            _listener.Bind(localEP);
            _listener.Listen(10000);

            if (OnStarted != null)
                OnStarted(this, new EventArgs());

            _iAmListening = true;

            var listenerWithCultureInfo = new Tuple<Socket, CultureInfo>(_listener,
                                                                         Thread.CurrentThread.CurrentUICulture);

            while (_iAmListening)
            {
                _allDone.Reset();
                _listener.BeginAccept(AcceptCallback, listenerWithCultureInfo);
                _allDone.WaitOne();
            }
        }
        catch (Exception exc)
        {
            Debug.Assert(false, exc.Message);
            if (OnException != null)
                OnException(this, new ExceptionEventArgs(exc, "Start"));
        }
    }

    public void StopListening()
    {
        try
        {
            _iAmListening = false;
            _allDone.Set();
        }
        catch(Exception exc)
        {
            Debug.Assert(false, exc.Message);
            if (OnException != null)
                OnException(this, new ExceptionEventArgs(exc, "StopListening"));
        }
    }

    public void Stop()
    {
        try
        {
            _listener.Close(0);
            CloseAllConnections();
            _listenerThread.Abort();
        }
        catch (Exception exc)
        {
            Debug.Assert(false, exc.Message);
            if (OnException != null)
                OnException(this, new ExceptionEventArgs(exc, "Stop"));
        }
    }

    private void AcceptCallback(IAsyncResult ar)
    {
        var arTuple = (Tuple<Socket, CultureInfo>)ar.AsyncState;
        var state = new StateObject(arTuple.Item2, InputBufferSize);

        try
        {
            Connections.AddOrUpdate(state.Guid,
                                    state,
                                    (k, v) => v);

            Thread.CurrentThread.CurrentUICulture = state.CurrentUICulture;

            var listener = arTuple.Item1;
            var handler = listener.EndAccept(ar);

            _allDone.Set();
            if (!_iAmListening)
                return;

            state.WorkSocket = handler;
            handler.BeginReceive(state.Buffer, 0, state.InputBufferSize, 0,
                                 RecieveCallBack, state);

            if (OnConnected != null)
                OnConnected(this, new ServerEventArgs(state));
        }
        catch(ObjectDisposedException)
        {
            _allDone.Set();
            return;
        }
        catch (Exception exc)
        {
            Debug.Assert(false, exc.Message);
            if (OnException != null)
                OnException(this, new ExceptionEventArgs(exc, state, "AcceptCallback"));
        }
    }

    public void RecieveCallBack(IAsyncResult ar)
    {
        var state = (StateObject)ar.AsyncState;

        try
        {
            Thread.CurrentThread.CurrentUICulture = state.CurrentUICulture;

            var handler = state.WorkSocket;
            var read = handler.EndReceive(ar);

            var pBinayDataPocketCodecStore = new BinayDataPocketCodecStore();

            if (read > 0)
            {
                state.LastDataReceive = DateTime.Now;

                var data = new byte[read];
                Array.Copy(state.Buffer, 0, data, 0, read);
                state.AddBytesToInputDataCollector(data);

                //check, if pocket is complete
                var allData = state.InputDataCollector.ToArray();
                var codecInitRes = pBinayDataPocketCodecStore.Check(allData);

                if (codecInitRes.Generic.Complete)
                {
                    if (!codecInitRes.Generic.Drop)
                    {
                        if (OnRecieved != null)
                            OnRecieved(this, new RecievedEventArgs(state, allData));
                    }
                    else
                    {
                        if (OnDropped != null)
                            OnDropped(this, new DroppedEventArgs(state, codecInitRes.Generic));

                        //get new data
                        state.ResetInputDataCollector();

                        handler.BeginReceive(state.Buffer, 0, state.InputBufferSize, 0,
                                             RecieveCallBack, state);
                    }
                }
                else
                {
                    //get more data
                    handler.BeginReceive(state.Buffer, 0, state.InputBufferSize, 0,
                                         RecieveCallBack, state);
                }
            }
            else
            {
                if ((handler.Connected == false) || (handler.Available == 0))
                {
                    Close(state);
                }
            }
        }
        catch (Exception exc)
        {
            Debug.Assert(false, exc.Message);
            if (OnException != null)
                OnException(this, new ExceptionEventArgs(exc, state, "RecieveCallBack"));
        }
    }

    public void Send(StateObject state, byte[] data)
    {
        try
        {
            var handler = state.WorkSocket;

            handler.BeginSend(data, 0, data.Length, 0,
                              SendCallback, state);
        }
        catch (Exception exc)
        {
            Debug.Assert(false, exc.Message);
            if (OnException != null)
                OnException(this, new ExceptionEventArgs(exc, state, "Send"));
        }
    }

    private void SendCallback(IAsyncResult ar)
    {
        var state = (StateObject)ar.AsyncState;

        try
        {
            Thread.CurrentThread.CurrentUICulture = state.CurrentUICulture;
            var handler = state.WorkSocket;

            handler.EndSend(ar);
            handler.BeginReceive(state.Buffer, 0, state.InputBufferSize, 0,
                                 RecieveCallBack, state);
        }
        catch (Exception exc)
        {
            Debug.Assert(false, exc.Message);
            if (OnException != null)
                OnException(this, new ExceptionEventArgs(exc, state, "SendCallback"));
        }
    }

    public void Close(StateObject state)
    {
        try
        {
            if (state == null)
                return;

            var handler = state.WorkSocket;

            if (handler == null)
                return;

            if (!handler.Connected)
                return;

            if (handler.Available > 0)
            {
                var data = new byte[handler.Available];
                handler.Receive(data);
            }

            handler.Shutdown(SocketShutdown.Both);
            handler.Close(0);

            if (OnDisconnected != null)
                OnDisconnected(this, new ServerEventArgs(state));

            StateObject removed;
            var removeResult = Connections.TryRemove(state.Guid, out removed);
        }
        catch (Exception exc)
        {
            Debug.Assert(false, exc.Message);
            if (OnException != null)
                OnException(this, new ExceptionEventArgs(exc, "Close"));
        }
    }

    private void CloseAllConnections()
    {
        try
        {
            var connections = Connections.Select(c => c.Value);

            foreach(var connection in connections)
            {
                Close(connection);
            }
        }
        catch(Exception exc)
        {
            Debug.Assert(false, exc.Message);
            if (OnException != null)
                OnException(this, new ExceptionEventArgs(exc, "CloseAllConnections"));
        }
    }

    public override string ToString()
    {
        return string.Format("{0}:{1}", IPAddress, Port);
    }
}
公共类设备cpserver
{
公共只读IP地址IP地址;
公共只读int端口;
公共只读int-InputBufferSize;
公共只读ConcurrentDictionary连接;
已启动公共事件处理程序;
公共事件处理程序;
公共事件服务器EventHandler未连接;
公共事件服务器EventHandler已断开连接;
公共事件收到处理者收到;
公共活动停止;
公共事件例外,例外情况除外;
公共事件ServerLogEventHandler ServerLog;
私人易变bool_;
私有套接字侦听器;
私有线程\u listenerThread;
private readonly ManualResetEvent _allDone=新的ManualResetEvent(错误);
公共广播收听
{
获取{return\u;}
}
公共设备CPServer(IPAddress IPAddress,
国际港口,
int inputBufferSize)
{
IP地址=IP地址;
端口=端口;
InputBufferSize=InputBufferSize;
连接=新的ConcurrentDictionary();
}
public void ThreadedStart()
{
_listenerThread=新线程(开始)
{
CurrentUICulture=Thread.CurrentThread.CurrentUICulture,
IsBackground=true
};
_listenerThread.Start();
}
私有void Start()
{
尝试
{
var localEP=新的IPEndPoint(IPAddress,端口);
_listener=新套接字(localEP.Address.AddressFamily,SocketType.Stream,ProtocolType.Tcp);
_Bind(localEP);
_听,听(10000);
如果(启动时!=null)
启动时(这是新的EventArgs());
_听=真;
var listenerWithCultureInfo=新元组(\u listener,
Thread.CurrentThread.CurrentUICulture);
边听
{
_全部完成。重置();
_beginacept(AcceptCallback,listenerWithCultureInfo);
_全部完成。WaitOne();
}
}
捕获(异常exc)
{
Assert(false,exc.Message);
if(OnException!=null)
一个例外情况(本,新的例外情况)(exc,“开始”);
}
}
公营部门
{
尝试
{
_听=假;
_allDone.Set();
}
捕获(异常exc)
{
Assert(false,exc.Message);
if(OnException!=null)
一个例外(这是一个新的例外,例如“停止监听”);
}
}
公共停车场()
{
尝试
{
_监听器关闭(0);
关闭所有连接();
_listenerThread.Abort();
}
捕获(异常exc)
{
Assert(false,exc.Message);
if(OnException!=null)
一个例外情况(本,新的例外情况)(exc,“停止”);
}
}
私有void AcceptCallback(IAsyncResult ar)
{
var arTuple=(Tuple)ar.AsyncState;
var state=新的StateObject(arTuple.Item2,InputBufferSize);
尝试
{
Connections.AddOrUpdate(state.Guid,
国家,,
(k,v)=>v);
Thread.CurrentThread.CurrentUICulture=state.CurrentUICulture;
var listener=arTuple.Item1;
var handler=listener.EndAccept(ar);
_allDone.Set();
如果(!\u)
返回;
state.WorkSocket=处理程序;
handler.BeginReceive(state.Buffer,0,state.InputBufferSize,0,
receiveCallback,state);
如果(未连接!=null)
OnConnected(这是新的ServerEventArgs(状态));
}
捕获(ObjectDisposedException)
{
_allDone.Set();
返回;
}
捕获(异常exc)
{
Assert(false,exc.Message);
if(OnException!=null)
OneException(这是新的ExceptionEventArgs(exc,状态为“AcceptCallback”);
}
}
公共无效ReceiveCallback(IAsyncResult ar)
{
var state=(StateObject)ar.AsyncState;
尝试
{
Thread.CurrentThread.CurrentUICulture=state.CurrentUICulture;
var handler=state.WorkSocket;
var read=handler.EndReceive(ar);
var pBinayDataPocketCodecStore=新的BinayDataPocketCodecStore();
如果(读取>0)
{
state.LastDataReceive=DateTime.Now;
变量数据=新字节[读取];
复制(state.Buffer,0,data,0,read);
state.AddBytesToInputDataCollector(数据);
//检查口袋是否完整
var allData=state.InputDataCollector.ToArray();
var codecInitRes=pBinayDataPocketCodecStore.Check(allData);
if(codecInitRes.Generic.Complete)