我使用此代码与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
}
}
答案 0 :(得分:0)
我在下面找到了链接。当我尝试从另一台计算机而不是localhost时,它工作正常!
TCP connection problems in Windows 8
Can't use StreamSocket to connect to a TcpListener
http://msdn.microsoft.com/en-us/library/windows/apps/Hh780593.aspx