Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 网络适配器关闭时检测客户端断开连接_C#_.net_Sockets_Tcp - Fatal编程技术网

C# 网络适配器关闭时检测客户端断开连接

C# 网络适配器关闭时检测客户端断开连接,c#,.net,sockets,tcp,C#,.net,Sockets,Tcp,我在检测客户端与主机断开连接时遇到问题。当前我的代码如下所示: Task.Run(() => { // Create server Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp) { ReceiveTimeout = -1, }; server.Bind(new IPEndPoint(IPAddress.Any, port)); serve

我在检测客户端与主机断开连接时遇到问题。当前我的代码如下所示:

Task.Run(() => {
 // Create server
 Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp) {
  ReceiveTimeout = -1,
 };

 server.Bind(new IPEndPoint(IPAddress.Any, port));
 server.Listen(-1);

 // Start listening
 while (true) {
  Socket socket = server.Accept();

  new Thread(() => {
   try {
    Process(socket);
   } catch (Exception ex) {
    Trace.WriteLine("Socket connection processing error: " + ex.Message);
   }
  }).Start();
 }
});

// Host client process
void Process(Socket socket) {
  byte[] response;
  int received;
  var ip = IPAddress.Parse(((IPEndPoint) socket.RemoteEndPoint).Address.ToString());
  Events.OnNodeConnected(ip);

  while (true) {
   // Rceive data
   response = new byte[socket.ReceiveBufferSize];
   received = socket.Receive(response);

   // Check connection
   if (!socket.IsConnected()) {
    socket.Close();
    Events.OnNodeDisconnected(ip);
    return;
   }

   try {
    // Decode recieved data
    List < byte > respBytesList = new List < byte > (response);

在关闭应用程序时工作,但在关闭网卡时不工作。我正在运行在VirtualBox上的Debian虚拟机上进行测试。在这种情况下,有没有办法检测到断开连接?

当我想知道我的网络接口是否已知时,我也有类似的问题

我使用这段代码检查不同的网络接口:

文件NetworkMonitor.cs

using System.Collections;
using System.Diagnostics;
using System.Timers;

namespace NetWork.Plus
{
    /// <summary>
    /// The NetworkMonitor class monitors network speed for each network adapter on the computer,
    /// using classes for Performance counter in .NET library.
    /// </summary>
    public class NetworkMonitor
    {
        private Timer timer;                        // The timer event executes every second to refresh the values in adapters.
        private ArrayList adapters;                 // The list of adapters on the computer.
        private ArrayList monitoredAdapters;        // The list of currently monitored adapters.

        public NetworkMonitor()
        {
            this.adapters   =   new ArrayList();
            this.monitoredAdapters  =   new ArrayList();
            EnumerateNetworkAdapters();

            timer   =   new Timer(1000);
            timer.Elapsed   +=  new ElapsedEventHandler(timer_Elapsed);
        }

        /// <summary>
        /// Enumerates network adapters installed on the computer.
        /// </summary>
        private void EnumerateNetworkAdapters()
        {
            PerformanceCounterCategory category =   new PerformanceCounterCategory("Network Interface");

            foreach (string name in category.GetInstanceNames())
            {
                // This one exists on every computer.
                if (name == "MS TCP Loopback interface")
                    continue;
                // Create an instance of NetworkAdapter class, and create performance counters for it.
                NetworkAdapter adapter  =   new NetworkAdapter(name);
                adapter.dlCounter   =   new PerformanceCounter("Network Interface", "Bytes Received/sec", name);
                adapter.ulCounter   =   new PerformanceCounter("Network Interface", "Bytes Sent/sec", name);
                this.adapters.Add(adapter);         // Add it to ArrayList adapter
            }
        }

        private void timer_Elapsed(object sender, ElapsedEventArgs e)
        {
            foreach (NetworkAdapter adapter in this.monitoredAdapters)
                adapter.refresh();
        }

        /// <summary>
        /// Get instances of NetworkAdapter for installed adapters on this computer.
        /// </summary>
        public NetworkAdapter[] Adapters
        {
            get
            {
                return (NetworkAdapter[])this.adapters.ToArray(typeof(NetworkAdapter));
            }
        }

        // Enable the timer and add all adapters to the monitoredAdapters list, unless the adapters list is empty.
        public void StartMonitoring()
        {
            if (this.adapters.Count > 0)
            {
                foreach(NetworkAdapter adapter in this.adapters)
                    if (!this.monitoredAdapters.Contains(adapter))
                    {
                        this.monitoredAdapters.Add(adapter);
                        adapter.init();
                    }

                timer.Enabled   =   true;
            }
        }

        // Enable the timer, and add the specified adapter to the monitoredAdapters list
        public void StartMonitoring(NetworkAdapter adapter)
        {
            if (!this.monitoredAdapters.Contains(adapter))
            {
                this.monitoredAdapters.Add(adapter);
                adapter.init();
            }
            timer.Enabled   =   true;
        }

        // Disable the timer, and clear the monitoredAdapters list.
        public void StopMonitoring()
        {
            this.monitoredAdapters.Clear();
            timer.Enabled   =   false;
        }

        // Remove the specified adapter from the monitoredAdapters list, and disable the timer if the monitoredAdapters list is empty.
        public void StopMonitoring(NetworkAdapter adapter)
        {
            if (this.monitoredAdapters.Contains(adapter))
                this.monitoredAdapters.Remove(adapter); 
            if(this.monitoredAdapters.Count == 0)
                timer.Enabled   =   false;
        }
    }
}



file NetworkAdapter.cs

using System.Diagnostics;

namespace NetWork.Plus
{
    /// <summary>
    /// Represents a network adapter installed on the machine.
    /// Properties of this class can be used to obtain current network speed.
    /// </summary>
    public class NetworkAdapter
    {
        /// <summary>
        /// Instances of this class are supposed to be created only in an NetworkMonitor.
        /// </summary>
        internal NetworkAdapter(string name)
        {
            this.name   =   name;
        }

        private long dlSpeed, ulSpeed;              // Download\Upload speed in bytes per second.
        private long dlValue, ulValue;              // Download\Upload counter value in bytes.
        private long dlValueOld, ulValueOld;        // Download\Upload counter value one second earlier, in bytes.

        internal string name;                               // The name of the adapter.
        internal PerformanceCounter dlCounter, ulCounter;   // Performance counters to monitor download and upload speed.

        /// <summary>
        /// Preparations for monitoring.
        /// </summary>
        internal void init()
        {
            // Since dlValueOld and ulValueOld are used in method refresh() to calculate network speed, they must have be initialized.
            this.dlValueOld =   this.dlCounter.NextSample().RawValue;
            this.ulValueOld =   this.ulCounter.NextSample().RawValue;
        }

        /// <summary>
        /// Obtain new sample from performance counters, and refresh the values saved in dlSpeed, ulSpeed, etc.
        /// This method is supposed to be called only in NetworkMonitor, one time every second.
        /// </summary>
        internal void refresh()
        {
            this.dlValue    =   this.dlCounter.NextSample().RawValue;
            this.ulValue    =   this.ulCounter.NextSample().RawValue;

            // Calculates download and upload speed.
            this.dlSpeed    =   this.dlValue - this.dlValueOld;
            this.ulSpeed    =   this.ulValue - this.ulValueOld;

            this.dlValueOld =   this.dlValue;
            this.ulValueOld =   this.ulValue;
        }

        /// <summary>
        /// Overrides method to return the name of the adapter.
        /// </summary>
        /// <returns>The name of the adapter.</returns>
        public override string ToString()
        {
            return this.name;
        }

        /// <summary>
        /// The name of the network adapter.
        /// </summary>
        public string Name
        {
            get
            {
                return this.name;
            }
        }
        /// <summary>
        /// Current download speed in bytes per second.
        /// </summary>
        public long DownloadSpeed
        {
            get
            {
                return this.dlSpeed;
            }
        }
        /// <summary>
        /// Current upload speed in bytes per second.
        /// </summary>
        public long UploadSpeed
        {
            get
            {
                return this.ulSpeed;
            }
        }
        /// <summary>
        /// Current download speed in kbytes per second.
        /// </summary>
        public double DownloadSpeedKbps
        {
            get
            {
                return this.dlSpeed/1024.0;
            }
        }
        /// <summary>
        /// Current upload speed in kbytes per second.
        /// </summary>
        public double UploadSpeedKbps
        {
            get
            {
                return this.ulSpeed/1024.0;
            }
        }
    }
}
您可以捕获网络设备列表,以便检查首选网络设备是已知的还是未知的

    monitor =   new NetworkMonitor();
    this.adapters   =   monitor.Adapters;
如果你愿意,你可以测量下载和/或上传的速度

按照framework的版本,您必须在exe.config文件中包含以下代码:(为了避免错误->无效操作:指定类别中不存在实例“XXX”)


在关闭应用程序时工作,但在关闭网卡时不工作

关闭网卡实际上并不是断开连接。如果网卡再次打开,现有连接可以继续(前提是接口仍然具有相同的IP地址)-这并不罕见,例如在挂起笔记本电脑并稍后恢复时

对于TCP,真正的断开连接只是一个显式断开连接(FIN gets send),它是在显式关闭套接字时完成的,或者是在应用程序退出或应用程序崩溃时由操作系统内核隐式完成的

相反,您要求的不是明确的断开连接,而是检测对等方当前是否无法连接,例如线路(暂时)断开连接或系统崩溃时。这可以通过在应用程序级别或TCP级别使用某种心跳来实现。后者称为TCP保持活动,通过发送空TCP数据包并检查是否发送回ACK来工作。有关如何使用此功能的示例,请参见

    private NetworkAdapter[] adapters;
    private NetworkMonitor monitor;   
    monitor =   new NetworkMonitor();
    this.adapters   =   monitor.Adapters;
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.net>
    <settings>
      <performanceCounters enabled="true" />
    </settings>
  </system.net>
</configuration>