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