C# Tcp客户端无法在WIN8上断开连接,但在WIN7上完全断开连接

C# Tcp客户端无法在WIN8上断开连接,但在WIN7上完全断开连接,c#,tcplistener,C#,Tcplistener,我使用此代码与tcp客户端通信。在WIN7上一切正常,但在WIN8上tcp客户端无法断开与服务器的连接。我使用Hercules软件来测试功能。所有tcp客户端都会联机断开与服务器的连接 DisconnectDevice(idx, devType, ip, port); 但在WIN8上,软件不属于这一类。等待你的想法 using System; using System.Collections.Generic; using System.Linq; using System.Text; usin

我使用此代码与tcp客户端通信。在WIN7上一切正常,但在WIN8上tcp客户端无法断开与服务器的连接。我使用Hercules软件来测试功能。所有tcp客户端都会联机断开与服务器的连接

DisconnectDevice(idx, devType, ip, port);
但在WIN8上,软件不属于这一类。等待你的想法

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Threading;
using Microsoft.Win32;

namespace OperationService.Comm
{
public sealed class Communication
{
    #region variables

    private static readonly Communication _instance = new Communication();

    #region low level communication

    private class _message
    {
        public const byte PACKET_START_CHAR = 0x23;
        public const int DATA_LENGTH_BYTE_NUM = 2;
        public const int EPOCH_BYTE_NUM = 4;
        public const byte PACKET_END_CHAR = 0x24;

        public enum State : int
        {
            Start,
            DataLength,
            Epoch,
            CmdType,
            Data,
            ChkSum,
            End
        }

        public byte Start { get; set; }
        public UInt16 DataLength { get; set; }
        public UInt32 Epoch { get; set; }
        public byte CmdType { get; set; }
        public byte[] Data { get; set; }
        public byte ChkSum { get; set; }
        public byte End { get; set; }

        public int DataLenCtr { get; set; }
        public int EpochCtr { get; set; }
        public int DataCtr { get; set; }
        public int CurrentChkSum { get; set; }

        public State MsgState { get; set; }

        public _message()
        {
            this.MsgState = State.Start;
            this.DataLenCtr = 0;
            this.EpochCtr = 0;
            this.DataCtr = 0;
            this.CurrentChkSum = 0;
        }
    }

    #endregion

    #region threading

    private const int MAX_TCP_BUFFER_LENGTH = 8192;
    private const int CLIENT_COMM_TASK_SLEEP_VALUE = 1000;
    private static bool _threadStartFlag;
    private static Thread _pmcListeningThread;
    private static Thread _pmdListeningThread;
    private static Thread _guiListeningThread;
    private static Thread _mobileListeningThread;
    private const int PMC_LISTENING_PORT = 1234;
    private const int PMD_LISTENING_PORT = 1233;
    private const int GUI_LISTENING_PORT = 1232;
    private const int MOBILE_LISTENING_PORT = 1231;
    private static string _localIp;
    private static string _mobileEntryIp;

    #endregion

    #endregion

    #region ctor

    private Communication()
    {
        _threadStartFlag = false;
        _localIp = Program.GetLocalIp();
        _mobileEntryIp = _localIp;
    }

    #endregion

    #region methods

    public static bool Initialize()
    {
        bool RetSt = false;

        try
        {
            if (!RunTasks())
                return false;

            RetSt = true;
        }
        catch (Exception ex)
        {
            Program.WriteEventLog(ex, EventLogEntryType.Error);
        }

        return RetSt;
    }

    public static bool Send(TcpClient tcpClient, List<byte> data)
    {
        Program.DebugWrite(tcpClient.ToString());
        for (int i = 0; i < data.Count; i++)
            Program.DebugWrite(data[i].ToString());
        return true;
    }

    private static bool RunTasks()
    {
        bool RetSt = false;

        try
        {
            if (!_threadStartFlag)
            {
                _pmcListeningThread = new Thread(() => ListeningTask(PMC_LISTENING_PORT));
                _pmcListeningThread.IsBackground = true;
                _pmcListeningThread.Start();

                _pmdListeningThread = new Thread(() => ListeningTask(PMD_LISTENING_PORT));
                _pmdListeningThread.IsBackground = true;
                _pmdListeningThread.Start();

                _guiListeningThread = new Thread(() => ListeningTask(GUI_LISTENING_PORT));
                _guiListeningThread.IsBackground = true;
                _guiListeningThread.Start();

                _mobileListeningThread = new Thread(() => ListeningTask(MOBILE_LISTENING_PORT));
                _mobileListeningThread.IsBackground = true;
                _mobileListeningThread.Start();

                _threadStartFlag = true;
            }

            RetSt = true;
        }
        catch (Exception ex)
        {
            Program.WriteEventLog(ex, EventLogEntryType.Error);
        }

        return RetSt;
    }

    private static void ListeningTask(int ListeningPort)
    {
        TcpListener tcpListener;

        try
        {
            tcpListener = new TcpListener(IPAddress.Any, ListeningPort);
            tcpListener.Start();
        }
        catch (Exception ex)
        {
            Program.WriteEventLog(ex, EventLogEntryType.Error);
            return;
        }

        Program.DebugWrite(string.Format("Tcp listener is active on Port:{0}.", ListeningPort));

        while (true)
        {
            try
            {
                TcpClient newTcpClient = tcpListener.AcceptTcpClient();
                string ip = ((IPEndPoint)newTcpClient.Client.RemoteEndPoint).Address.ToString();
                string port = ((IPEndPoint)newTcpClient.Client.RemoteEndPoint).Port.ToString();

                int idx = -1;
                DeviceType devType;
                bool isOnline = false;
                bool isAllowed = false;

                if (ListeningPort == PMC_LISTENING_PORT)
                {
                    devType = DeviceType.Controller;

                    idx = Program.Topology.Controllers.FindIndex(c => c.Ip == ip);
                    if (idx >= 0)
                    {
                        if (!object.ReferenceEquals(Program.Topology.Controllers[idx], null))
                        {
                            isAllowed = true;
                            if (Program.Topology.Controllers[idx].Runtime.IsOnline)
                                isOnline = true;
                        }
                    }
                }
                else if (ListeningPort == PMD_LISTENING_PORT)
                {
                    devType = DeviceType.Display;

                    idx = Program.Topology.Displays.FindIndex(d => d.Ip == ip);
                    if (idx >= 0)
                    {
                        if (!object.ReferenceEquals(Program.Topology.Displays[idx], null))
                        {
                            isAllowed = true;
                            if (Program.Topology.Displays[idx].Runtime.IsOnline)
                                isOnline = true;
                        }
                    }
                }
                else if (ListeningPort == GUI_LISTENING_PORT)
                {
                    devType = DeviceType.Gui;

                    if (ip == _localIp)
                    {
                        isAllowed = true;
                        if (Program.Topology.Gui.IsOnline)
                            isOnline = true;
                    }

                }
                else if (ListeningPort == MOBILE_LISTENING_PORT)
                {
                    devType = DeviceType.Mobile;

                    if (ip == _mobileEntryIp)
                    {
                        isAllowed = true;
                        isOnline = false;
                    }
                }
                else
                    return;

                if (isAllowed)
                {
                    if (!isOnline)
                    {
                        CreateTcpClient(idx, devType, newTcpClient);
                        ConnectDevice(idx, devType, ip, port);

                        Thread ClientCommThread = new Thread(() => ClientCommTask(idx, devType, newTcpClient, ip, port));
                        ClientCommThread.IsBackground = true;
                        ClientCommThread.Start();
                    }
                    else
                    {
                        Program.WriteEventLog(string.Format("Tcp client from IP:{0} and Port:{1} is already online.", ip, port), EventLogEntryType.Warning);
                        newTcpClient.Close();
                    }
                }
                else
                {
                    Program.WriteEventLog(string.Format("Unauthorized connection attempt from IP:{0} and Port:{1}.", ip, port), EventLogEntryType.Warning);
                    newTcpClient.Close();
                }
            }
            catch (SocketException ex)
            {
                Program.WriteEventLog(ex, EventLogEntryType.Error);
            }
            catch (Exception ex)
            {
                Program.WriteEventLog(ex, EventLogEntryType.Error);
            }
        }
    }

    private static void ClientCommTask(int idx, DeviceType devType, TcpClient tcpClient, string ip, string port)
    {
        NetworkStream ClientDataStream = tcpClient.GetStream();
        _message msg = new _message();

        byte[] Data = new byte[MAX_TCP_BUFFER_LENGTH];
        int DataLen;

        while (true)
        {
            try
            {
                try
                {
                    DataLen = ClientDataStream.Read(Data, 0, Data.Length);
                }
                catch
                {
                    // network stream data is not avaliable in urgent case use
                    DataLen = 0;
                }

                if (DataLen == 0)
                {
                    // the client has disconnected from the server
                    DisconnectDevice(idx, devType, ip, port);
                    break;
                }
                else
                {

                }

                Thread.Sleep(CLIENT_COMM_TASK_SLEEP_VALUE);
            }
            catch (Exception ex)
            {
                Program.WriteEventLog(ex, EventLogEntryType.Error);
            }
        }

        DisposeTcpClient(idx, devType, tcpClient);
    }

    private static void ParseMsg(_message msg)
    {
        try
        {
            switch (msg.CmdType)
            { 
                case 0x00:
                    if (Program.Topology.Gui.IsOnline)
                        Console.WriteLine("gui on");
                    else
                        Console.WriteLine("gui off");
                    break;
            }
        }
        catch (Exception ex)
        {
            Program.WriteEventLog(ex, EventLogEntryType.Error);
        }
    }

    private static void ConnectDevice(int idx, DeviceType devType, string ip, string port)
    {
        try
        {
            if (devType == DeviceType.Controller)
            {
                Program.WriteEventLog(string.Format("Controller device from IP:{0} and Port:{1} connected.", ip, port), EventLogEntryType.Information);
                Program.Topology.Controllers[idx].Runtime.IsOnline = true;
                Program.Topology.Controllers[idx].Runtime.Port = int.Parse(port);
                Program.Topology.Controllers[idx].Runtime.Ip = ip;
            }
            else if (devType == DeviceType.Display)
            {
                Program.WriteEventLog(string.Format("Display device from IP:{0} and Port:{1} connected.", ip, port), EventLogEntryType.Information);
                Program.Topology.Displays[idx].Runtime.IsOnline = true;
                Program.Topology.Displays[idx].Runtime.Port = int.Parse(port);
                Program.Topology.Displays[idx].Runtime.Ip = ip;
            }
            else if (devType == DeviceType.Gui)
            {
                Program.WriteEventLog(string.Format("Gui device from IP:{0} and Port:{1} connected.", ip, port), EventLogEntryType.Information);
                Program.Topology.Gui.IsOnline = true;
                Program.Topology.Gui.Port = int.Parse(port);
                Program.Topology.Gui.Ip = ip;
            }
            else if (devType == DeviceType.Mobile)
            {
                Program.WriteEventLog(string.Format("Mobile device from IP:{0} and Port:{1} connected.", ip, port), EventLogEntryType.Information);
            }
        }
        catch (Exception ex)
        {
            Program.WriteEventLog(ex, EventLogEntryType.Error);
        }
    }

    private static void DisconnectDevice(int idx, DeviceType devType, string ip, string port)
    { 
        try
        {
            if (devType == DeviceType.Controller)
            {
                Program.WriteEventLog(string.Format("Controller device from IP:{0} and Port:{1} disconnected.", ip, port), EventLogEntryType.Warning);
                Program.Topology.Controllers[idx].Runtime.IsOnline = false;
                Program.Topology.Controllers[idx].Runtime.Port = -1;
                Program.Topology.Controllers[idx].Runtime.Ip = string.Empty;
            }
            else if (devType == DeviceType.Display)
            {
                Program.WriteEventLog(string.Format("Display device from IP:{0} and Port:{1} disconnected.", ip, port), EventLogEntryType.Warning);
                Program.Topology.Displays[idx].Runtime.IsOnline = false;
                Program.Topology.Displays[idx].Runtime.Port = -1;
                Program.Topology.Displays[idx].Runtime.Ip = string.Empty;
            }
            else if (devType == DeviceType.Gui)
            {
                Program.WriteEventLog(string.Format("Gui device from IP:{0} and Port:{1} disconnected.", ip, port), EventLogEntryType.Warning);
                Program.Topology.Gui.IsOnline = false;
                Program.Topology.Gui.Port = -1;
                Program.Topology.Gui.Ip = string.Empty;
            }
            else if (devType == DeviceType.Mobile)
            {
                Program.WriteEventLog(string.Format("Mobile device from IP:{0} and Port:{1} disconnected.", ip, port), EventLogEntryType.Warning);
            }
        }
        catch (Exception ex)
        {
            Program.WriteEventLog(ex, EventLogEntryType.Error);
        }
    }

    private static void CreateTcpClient(int idx, DeviceType devType, TcpClient client)
    {
        try
        {
            if (devType == DeviceType.Controller)
            {
                Program.Topology.Controllers[idx].Runtime.TcpClient = client;
            }
            else if (devType == DeviceType.Display)
            {
                Program.Topology.Displays[idx].Runtime.TcpClient = client;
            }
            else if (devType == DeviceType.Gui)
            {
                Program.Topology.Gui.TcpClient = client;
            }
            else if (devType == DeviceType.Mobile)
            {
            }
        }
        catch (Exception ex)
        {
            Program.WriteEventLog(ex, EventLogEntryType.Error);
        }
    }

    private static void DisposeTcpClient(int idx, DeviceType devType, TcpClient client)
    {
        try
        {
            if (devType == DeviceType.Controller)
            {
                Program.Topology.Controllers[idx].Runtime.TcpClient.Client.Close();
                Program.Topology.Controllers[idx].Runtime.TcpClient = null;
            }
            else if (devType == DeviceType.Display)
            {
                Program.Topology.Displays[idx].Runtime.TcpClient.Client.Close();
                Program.Topology.Displays[idx].Runtime.TcpClient = null;
            }
            else if (devType == DeviceType.Gui)
            {
                Program.Topology.Gui.TcpClient.Client.Close();
                Program.Topology.Gui.TcpClient = null;
            }
            else if (devType == DeviceType.Mobile)
            {
                client.Client.Close();
                client = null;
            }
        }
        catch (Exception ex)
        {
            Program.WriteEventLog(ex, EventLogEntryType.Error);
        }
    }

    #endregion
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用系统诊断;
Net系统;
使用System.Net.NetworkInformation;
使用System.Net.Sockets;
使用系统线程;
使用Microsoft.Win32;
名称空间操作服务.Comm
{
公开保密通信
{
#区域变量
私有静态只读通信_实例=新通信();
#区域低级别通信
私有类消息
{
公共常量字节数据包\u开始\u字符=0x23;
public const int DATA_LENGTH_BYTE_NUM=2;
公共常量int历元字节数=4;
public const byte PACKET\u END\u CHAR=0x24;
公共枚举状态:int
{
开始
数据长度,
纪元
CmdType,
数据,
切克萨姆,
终点
}
公共字节开始{get;set;}
公共UInt16数据长度{get;set;}
公共UInt32历元{get;set;}
公共字节CmdType{get;set;}
公共字节[]数据{get;set;}
公共字节ChkSum{get;set;}
公共字节结束{get;set;}
public int DataLenCtr{get;set;}
公共点EpochCtr{get;set;}
public int DataCtr{get;set;}
public int CurrentChkSum{get;set;}
公共状态MsgState{get;set;}
公共信息
{
this.MsgState=State.Start;
此.DataLenCtr=0;
此参数为0.EpochCtr=0;
这个.DataCtr=0;
此.CurrentChkSum=0;
}
}
#端区
#区域线程
private const int MAX_TCP_BUFFER_LENGTH=8192;
private const int CLIENT_COMM_TASK_SLEEP_VALUE=1000;
私有静态bool_threadStartFlag;
私有静态线程\u pmcListeningThread;
私有静态线程_pmdlistingthread;
私有静态线程_guilistengthread;
私有静态线程\u mobileListeningThread;
专用常量int PMC\u侦听端口=1234;
专用常量int PMD_侦听_端口=1233;
私有const int GUI_监听端口=1232;
移动监听端口的专用常数=1231;
私有静态字符串_localIp;
私有静态字符串_mobileentryp;
#端区
#端区
#区域导体
私人通讯()
{
_threadStartFlag=false;
_localIp=Program.GetLocalIp();
_mobileEntryIp=_localIp;
}
#端区
#区域方法
公共静态bool初始化()
{
bool-RetSt=false;
尝试
{
如果(!RunTasks())
返回false;
RetSt=真;
}
捕获(例外情况除外)
{
Program.WriteEventLog(例如,EventLogEntryType.Error);
}
返回RetSt;
}
公共静态bool发送(TcpClient TcpClient,列表数据)
{
Program.DebugWrite(tcpClient.ToString());
for(int i=0;iListeningTask(PMC_侦听_端口));
_pmcListeningThread.IsBackground=true;
_pmcListeningThread.Start();
_PMDListingThread=新线程(()=>ListeningTask(PMD_侦听_端口));
_pmdlistingthread.IsBackground=true;
_pmdlistingthread.Start();
_guilistengthread=新线程(()=>listengtask(GUI_侦听_端口));
_guiListeningThread.IsBackground=true;
_guiListengThread.Start();
_mobileListeningThread=新线程(()=>ListeningTask(移动侦听端口));
_mobileListeningThread.IsBackground=true;
_mobileListeningThread.Start();
_threadStartFlag=true;
}
RetSt=真;
}
捕获(例外情况除外)
{
Program.WriteEventLog(例如,EventLogEntryType.Error);
}
返回RetSt;
}
私有静态void ListingTask(int ListingPort)
{
TcpListener TcpListener;
尝试
{
tcpListener=新的tcpListener(IPAddress.Any,listingport);
tcpListener.Start();
}
捕获(例外情况除外)
{
Program.WriteEventLog(例如,EventLogEntryType.Error);
返回;
}
Program.DebugWrite(string.Format(“Tcp侦听器在端口:{0}.”,ListeningPort上处于活动状态”);
while(true)
{
尝试
{
TcpClient newTcpClient=tcpListener.AcceptTcpClient();
字符串ip=((IPEndPoint)newTcpClient.Client.RemoteEndPoint).Address.ToString();
字符串端口=((IPEndPoint)newTcpClient.Client.RemoteEndPoint.port.ToString();
intidx=-1;
设备类型devType;
bool isOnline=false;
bool isAllowed=false;
如果(ListingPort==PMC\u侦听\u端口)
{
devType=设备类型控制器;
idx=Program.Topology.Controller.FindIndex(c=>c.Ip==Ip);
如果(idx>=0)
{
如果(!object.ReferenceEquals(Program.Topology.Controller[idx],null))
{
isAllowed=正确;