2013-03-25 3 views
0

이 코드를 사용하여 TCP 클라이언트와 통신합니다. WIN7에서는 모든 것이 잘 작동하지만 WIN8에서는 클라이언트가 서버에서 연결을 끊을 수 없습니다. 기능을 테스트하기 위해 Hercules 소프트웨어를 사용합니다. 모든 tcp 클라이언트는 서버의 라인에서 서버와의 연결을 끊습니다.Tcp 클라이언트는 WIN8에서 연결을 끊을 수 없지만 WIN7에서는 완벽하게 연결을 끊을 수 있습니다.

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 
} 

}

답변

관련 문제