C# Tcp客户端无法在WIN8上断开连接,但在WIN7上完全断开连接
我使用此代码与tcp客户端通信。在WIN7上一切正常,但在WIN8上tcp客户端无法断开与服务器的连接。我使用Hercules软件来测试功能。所有tcp客户端都会联机断开与服务器的连接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
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=正确;