我有一个小的方法来禁用我的套接字来监听传入的连接。套接字断开行为
/// <summary>
/// Stops and disables the service
/// </summary>
public void Disable() {
if (Running) {
try {
thread.Abort();
}
catch (System.Threading.ThreadAbortException) {
// This catch is not raised.
// We can simply process our closing of the socket and nullify the thread
}
finally {
socket.Close();
socket = null;
thread = null;
if (socket == null && thread == null) {
m_Running = false;
OnDisabled(this, new EventArgs());
}
}
}
}
我的问题是,即使在我调用Close()并使套接字无效后,客户端仍保持连接状态。我使用netstat -a运行了一个检查,并显示客户端仍然连接。
TCP 127.0.0.1:2161 activate:7777 ESTABLISHED
TCP 127.0.0.1:7777 activate:2161 ESTABLISHED
7777是我的主机套接字侦听的端口。所以我的问题是,关闭主机套接字后,为什么客户端套接字不能断开连接。他们如何保持连接到一个空的套接字,并不再听取?
一些额外的信息
/// <summary>
/// Enables and runs the service
/// </summary>
public void Enable() {
if (!Running) {
ThreadStart start = new ThreadStart(RunServiceAsync);
thread = new Thread(start);
thread.IsBackground = true;
thread.Start();
m_Running = true;
OnEnabled(this, new EventArgs());
}
}
上述方法是线程的创建方式。一切正常,线程,连接;唯一的问题是,当我关闭套接字(主机),并取消它的客户端仍然连接到它。
问题是,一旦主机套接字关闭并设置为空,客户端连接到了什么?它们不应该断开连接并且失去与主机的连接,因为主机套接字已关闭?
以下是完整的代码,以帮助
// *********************************************************************
// [DCOM制作] // [版权所有(C)DCOM制作全部保留。权利] // * * * * ** * ** * ** * ** * ** * ** * ** * ** * ** * ** * ** * **
命名空间使用CipherBox.Drivers { 系统; using System.Collections.Generic;使用System.Linq的 ; using System.Text;使用System.Threading的 ;使用System.Net.Sockets的 ;使用System.Net的 ; using System.ComponentModel;使用CipherBox.Objects的 ;
/// <summary>
/// Driver that manages the network connection between the master program and clients, also provides informational events
/// </summary>
public class NetworkDriver : IDriver {
#region Fields
private Socket socket;
private Thread thread;
#endregion
#region Properties
private int m_Port = 7777;
/// <summary>
/// Gets the port that the network runs on. The default port is 7777.
/// </summary>
public int Port {
get {
return m_Port;
}
}
#endregion
#region Events
/// <summary>
/// Delegate for when a node connects to the service
/// </summary>
public delegate void NodeConnectedEventHandler(object sender, NetworkNodeEventArgs e);
/// <summary>
/// Triggers when an node connects to the service
/// </summary>
public event NodeConnectedEventHandler NodeConnected;
/// <summary>
/// Event callback for NodeConnected
/// </summary>
private void OnNodeConnected(object sender, NetworkNodeEventArgs e) {
if (NodeConnected != null) {
foreach (NodeConnectedEventHandler handler in NodeConnected.GetInvocationList()) {
ISynchronizeInvoke syncInvoke = handler.Target as ISynchronizeInvoke;
if (syncInvoke != null && syncInvoke.InvokeRequired) {
syncInvoke.Invoke(handler, new object[] { handler.Target, e });
}
else {
NodeConnected(this, e);
}
}
}
}
/// <summary>
/// Delegate for when a node disconnects from the service
/// </summary>
public delegate void NodeDisconnectedEventHandler(object sender, NetworkNodeEventArgs e);
/// <summary>
/// Triggers when an node disconnects from the service
/// </summary>
public event NodeDisconnectedEventHandler NodeDisconnected;
/// <summary>
/// Event callback for NodeDisconnected
/// </summary>
private void OnNodeDisconnected(object sender, NetworkNodeEventArgs e) {
if (NodeDisconnected != null) {
foreach (NodeDisconnectedEventHandler handler in NodeDisconnected.GetInvocationList()) {
ISynchronizeInvoke syncInvoke = handler.Target as ISynchronizeInvoke;
if (syncInvoke != null && syncInvoke.InvokeRequired) {
syncInvoke.Invoke(handler, new object[] { handler.Target, e });
}
else {
NodeDisconnected(this, e);
}
}
}
}
#endregion
#region Methods
private NetworkNode FillNode(Socket socket) {
StringBuilder stream = new StringBuilder();
byte[] buffer = new byte[4096];
int bytesReceived = -1;
do {
try {
bytesReceived = socket.Receive(buffer, 0, buffer.Length, SocketFlags.None);
}
catch (System.Net.Sockets.SocketException) {
return null;
}
finally {
stream.Append(Encoding.ASCII.GetString(buffer, 0, bytesReceived));
}
} while (!stream.ToString().EndsWith("\r\n\r\n"));
string[] packet = stream.ToString().Split(new string[] { "\r\n" }, StringSplitOptions.None);
if (packet.Length == 9) {
if (packet[0].ToLower() == "CipherBox".ToLower()) {
NetworkNode node = new NetworkNode();
node.Domain = packet[1];
node.LocalIP = IPAddress.Parse(packet[2]);
node.MachineName = packet[3];
node.Platform = packet[4];
node.RemoteIP = IPAddress.Parse(packet[5]);
node.Workgroup = packet[6];
node.Socket = socket;
return node;
}
else {
return null;
}
}
else {
return null;
}
}
private bool IsDisconnected(Socket socket) {
bool connected = false;
try {
connected = !(socket.Poll(1, SelectMode.SelectRead) && socket.Available == 0);
}
catch (System.Net.Sockets.SocketException) {
connected = false;
}
return !connected;
}
private void MonitorNode(NetworkNode node) {
ParameterizedThreadStart start = new ParameterizedThreadStart(MonitorNodeAsync);
Thread thread = new Thread(start);
thread.IsBackground = true;
thread.Start(node);
}
private void MonitorNodeAsync(object obj) {
NetworkNode node = obj as NetworkNode;
while (Running || node != null) {
if (IsDisconnected(node.Socket)) {
node.Socket.Shutdown(SocketShutdown.Both);
node.Socket.Close();
node.Socket = null;
OnNodeDisconnected(null, new NetworkNodeEventArgs(node));
return;
}
else {
Thread.Sleep(1000);
}
}
}
private void RunServiceAsync() {
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint localEP = new IPEndPoint(IPAddress.Any, Port);
socket.Bind(localEP);
socket.Listen(1);
do {
Socket client;
try {
client = socket.Accept();
}
catch (System.Net.Sockets.SocketException) {
continue;
}
NetworkNode node = FillNode(client);
if (node != null) {
OnNodeConnected(null, new NetworkNodeEventArgs(node));
MonitorNode(node);
}
} while (Running);
}
/// <summary>
/// Sets the port that the network runs on
/// </summary>
/// <param name="port">The port to set</param>
public void SetPort(int port) {
m_Port = port;
}
#endregion
#region IDriver Members
/// <summary>
/// Triggered when the network driver is disabled
/// </summary>
public event EventHandler<EventArgs> Disabled;
/// <summary>
/// Event callback for Disabled
/// </summary>
private void OnDisabled(object sender, System.EventArgs e) {
if (Disabled != null) {
foreach (EventHandler<EventArgs> handler in Disabled.GetInvocationList()) {
ISynchronizeInvoke syncInvoke = handler.Target as ISynchronizeInvoke;
if (syncInvoke != null && syncInvoke.InvokeRequired) {
syncInvoke.Invoke(handler, new object[] { handler.Target, e });
}
else {
Disabled(this, e);
}
}
}
}
/// <summary>
/// Triggered when the network driver is enabled
/// </summary>
public event EventHandler<EventArgs> Enabled;
/// <summary>
/// Event callback for Enabled
/// </summary>
private void OnEnabled(object sender, System.EventArgs e) {
if (Enabled != null) {
foreach (EventHandler<EventArgs> handler in Enabled.GetInvocationList()) {
ISynchronizeInvoke syncInvoke = handler.Target as ISynchronizeInvoke;
if (syncInvoke != null && syncInvoke.InvokeRequired) {
syncInvoke.Invoke(handler, new object[] { handler.Target, e });
}
else {
Enabled(this, e);
}
}
}
}
/// <summary>
/// Stops and disables the service
/// </summary>
public void Disable() {
if (Running) {
try {
thread.Abort();
}
catch (System.Threading.ThreadAbortException) {
// This catch is not raised.
// We can simply process our closing of the socket and nullify the thread
}
finally {
socket.Close();
socket = null;
thread = null;
if (socket == null && thread == null) {
m_Running = false;
OnDisabled(this, new EventArgs());
}
}
}
}
/// <summary>
/// Enables and runs the service
/// </summary>
public void Enable() {
if (!Running) {
ThreadStart start = new ThreadStart(RunServiceAsync);
thread = new Thread(start);
thread.IsBackground = true;
thread.Start();
m_Running = true;
OnEnabled(this, new EventArgs());
}
}
private bool m_Running = false;
/// <summary>
/// Gets a System.Boolean value indicating whether the service is running or not
/// </summary>
public bool Running {
get {
return m_Running;
}
}
#endregion
}
}
相关? http://stackoverflow.com/questions/3137274/thread-abort-doesnt-seem-to-throw-a-threadabortexception-because-of-acceptsocket – Lazlo 2010-11-24 04:48:30
哇......这个`线程`被中止了什么?这是当前线程吗?如果没有,那么为什么你将它包装到`ThreadAbortException`处理程序中? `thread`和`socket`的范围是什么?我假设示例代码是针对“主持人”的......您究竟如何倾听?你使用`Socket.Accept()`?这创建另一个套接字对象。关闭监听器就是这样 - 停止监听新连接。 – 2010-11-24 04:51:21