格式化代码

This commit is contained in:
zhengxuan.zhang
2024-02-21 17:05:21 +08:00
parent 4c87a3c425
commit 08daf2ced4
11 changed files with 1061 additions and 1077 deletions
+130 -135
View File
@@ -1,25 +1,22 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using Timer = System.Windows.Forms.Timer;
namespace HexcalMC.Hexcal
{
public class TcpIpServer
{
/// <summary>
/// 使用模式,默认=1,接收任意数据显示;2=前两个字节为数据长度
/// </summary>
public int UseMode = 1;
public delegate void EventHandlerRaisedMessage(string clientIp, string msg);
string strServerIP = "127.0.0.1"; //服务器的IP地址
string strServerPort = "8080"; //端口号
public enum EnumTcpIpServer : int
public delegate void EventHandlerRaisedStatus(EnumTcpIpServer type, string msg);
public enum EnumTcpIpServer
{
StartListen = 1,
ClientConnect = 2,
@@ -28,68 +25,55 @@ namespace HexcalMC.Hexcal
Exception = -1
}
#region 510,
private readonly Dictionary<string, Socket> _dictSocket = new Dictionary<string, Socket>();
private readonly Dictionary<string, Thread> _dictThread = new Dictionary<string, Thread>();
private Socket _mWatchSocket;
System.Windows.Forms.Timer ServerTimer = new System.Windows.Forms.Timer();
private Thread _mWatchThread; // 负责监听客户端连接请求的线程;
private void ServerTimerLoop(object sender, EventArgs e)
private readonly string _strServerIp = "127.0.0.1"; //服务器的IP地址
private readonly string _strServerPort = "8080"; //端口号
/// <summary>
/// 使用模式,默认=1,接收任意数据显示;2=前两个字节为数据长度
/// </summary>
public int UseMode = 1;
//=========================================================================
public TcpIpServer(string serverIp, string serverPort)
{
ServerTimer.Interval = 20000; //监听timer的间隔
if (DictSocket != null)
{
if (DictSocket.Count != 0)
{
DictSocket.Values.ToArray();
for (int i = DictSocket.Values.ToArray().Length - 1; i >= 0; i--)
{
if (DictSocket.Values.ToArray()[i].Poll(10, SelectMode.SelectRead)) //10毫秒,检查套接字状态, SelectMode 参数指定要监视的套接字的类别。
{
// DictSocket.Remove(DictSocket.Keys.ToArray()[i]);
_strServerIp = serverIp;
_strServerPort = serverPort;
}
RaisedStatus(EnumTcpIpServer.ConnectException,
"连接已断开:" + DictSocket.Keys.ToArray()[i]); //刷新界面显示,触发一个连接异常状态枚举,并将消息传递为异常的状态
RemoveSocketClient(DictSocket.Keys.ToArray()[i]);
}
}
}
public string[] SocketNames => _dictSocket.Keys.ToArray();
public bool ConnectStatus
{
get
{
if (_mWatchSocket == null)
return false;
return _mWatchSocket.Connected && _mWatchThread != null;
}
}
#endregion
Thread m_WatchThread = null; // 负责监听客户端连接请求的线程;
Socket m_WatchSocket = null;
Dictionary<string, Thread> DictThread = new Dictionary<string, Thread>();
Dictionary<string, Socket> DictSocket = new Dictionary<string, Socket>();
bool bStartListen = false;
public string[] SocketNames
{
get { return (string[])DictSocket.Keys.ToArray(); }
}
//=========================================================================
public TcpIpServer(string ServerIP, string ServerPort)
{
strServerIP = ServerIP;
strServerPort = ServerPort;
}
public bool WatchStatus { get; private set; }
public bool StartListen()
{
try
{
ServerTimer.Tick += new EventHandler(ServerTimerLoop); //510,增加时钟,判断是否有断掉的连接。
ServerTimer.Start();
_serverTimer.Tick += ServerTimerLoop; //510,增加时钟,判断是否有断掉的连接。
_serverTimer.Start();
m_WatchSocket =
_mWatchSocket =
new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //创建负责监听的套接字,注意其中的参数;
IPAddress m_IpAddr = IPAddress.Parse(strServerIP); //获得文本框中的IP对象;
IPEndPoint m_EndPoint = new IPEndPoint(m_IpAddr, int.Parse(strServerPort)); //创建包含ip和端口号的网络节点对象;
IPAddress mIpAddr = IPAddress.Parse(_strServerIp); //获得文本框中的IP对象;
IPEndPoint mEndPoint = new IPEndPoint(mIpAddr, int.Parse(_strServerPort)); //创建包含ip和端口号的网络节点对象;
try
{
m_WatchSocket.Bind(m_EndPoint); // 将负责监听的套接字绑定到唯一的ip和端口上;
_mWatchSocket.Bind(mEndPoint); // 将负责监听的套接字绑定到唯一的ip和端口上;
}
catch (SocketException se)
{
@@ -97,12 +81,12 @@ namespace HexcalMC.Hexcal
return false;
}
bStartListen = true;
m_WatchSocket.Listen(10); // 设置监听队列的长度
m_WatchThread = new Thread(WatchThread); // 创建负责监听的线程
m_WatchThread.IsBackground = true;
m_WatchThread.Start();
RaisedStatus(EnumTcpIpServer.StartListen, "服务器启动监听成功!IP=" + strServerIP + ", Port=" + strServerPort);
WatchStatus = true;
_mWatchSocket.Listen(10); // 设置监听队列的长度
_mWatchThread = new Thread(WatchThread); // 创建负责监听的线程
_mWatchThread.IsBackground = true;
_mWatchThread.Start();
RaisedStatus(EnumTcpIpServer.StartListen, "服务器启动监听成功!IP=" + _strServerIp + ", Port=" + _strServerPort);
return true;
}
catch (Exception ex)
@@ -116,75 +100,58 @@ namespace HexcalMC.Hexcal
{
try
{
bStartListen = false;
m_WatchSocket.Close();
m_WatchSocket.Dispose();
m_WatchSocket = null;
WatchStatus = false;
_mWatchSocket.Close();
_mWatchSocket.Dispose();
_mWatchSocket = null;
DictThread.Clear();
DictSocket.Clear();
_dictThread.Clear();
_dictSocket.Clear();
}
catch
{
}
}
public bool ConnectStatus
{
get
{
if (m_WatchSocket == null)
return false;
return m_WatchSocket.Connected && m_WatchThread != null;
}
}
public bool WatchStatus
{
get { return bStartListen; }
}
//监听线程
void WatchThread()
private void WatchThread()
{
try
{
while (bStartListen) // 持续不断的监听客户端的连接请求;
while (WatchStatus) // 持续不断的监听客户端的连接请求;
{
// 开始监听客户端连接请求,Accept方法会阻断当前的线程;
Socket sokClient = m_WatchSocket.Accept(); // 一旦监听到一个客户端的请求,就返回一个与该客户端通信的套接字;
Socket sokClient = _mWatchSocket.Accept(); // 一旦监听到一个客户端的请求,就返回一个与该客户端通信的套接字;
#region
#region 510,
if (DictSocket != null)
if (_dictSocket != null)
{
if (DictSocket.Count != 0)
if (_dictSocket.Count != 0)
{
DictSocket.Values.ToArray();
for (int i = DictSocket.Values.ToArray().Length - 1; i >= 0; i--)
_dictSocket.Values.ToArray();
for (int i = _dictSocket.Values.ToArray().Length - 1; i >= 0; i--)
{
if (DictSocket.Values.ToArray()[i].Poll(10, SelectMode.SelectRead))
if (_dictSocket.Values.ToArray()[i].Poll(10, SelectMode.SelectRead))
{
//DictSocket.Remove(DictSocket.Keys.ToArray()[i]);
RemoveSocketClient(DictSocket.Keys.ToArray()[i]);
RemoveSocketClient(_dictSocket.Keys.ToArray()[i]);
}
}
}
}
#endregion
#endregion
DictSocket.Add(sokClient.RemoteEndPoint.ToString(), sokClient); // 将与客户端连接的套接字对象添加到集合中;
_dictSocket.Add(sokClient.RemoteEndPoint.ToString(), sokClient); // 将与客户端连接的套接字对象添加到集合中;
RaisedStatus(EnumTcpIpServer.ClientConnect,
"客户端连接成功!RemoteEndPoint=" + sokClient.RemoteEndPoint.ToString());
"客户端连接成功!RemoteEndPoint=" + sokClient.RemoteEndPoint);
Thread thread = new Thread(ReceiveThread);
thread.IsBackground = true;
thread.Start(sokClient);
DictThread.Add(sokClient.RemoteEndPoint.ToString(), thread); // 将新建的线程 添加 到线程的集合中去。
_dictThread.Add(sokClient.RemoteEndPoint.ToString(), thread); // 将新建的线程 添加 到线程的集合中去。
}
}
catch
@@ -193,10 +160,10 @@ namespace HexcalMC.Hexcal
}
//接收线程
void ReceiveThread(object sokObj)
private void ReceiveThread(object sokObj)
{
Socket sokClient = sokObj as Socket;
while (bStartListen)
while (WatchStatus)
{
// 定义一个2M的缓存区;
byte[] arrMsgRec = new byte[sokClient.Available];
@@ -226,9 +193,9 @@ namespace HexcalMC.Hexcal
if (length > 0)
{
// TcpIpDfn.SongLiang_arrMsgRec = arrMsgRec; //510
string strData = System.Text.Encoding.Default.GetString(arrMsgRec); // 将接受到的字节数据转化成字符串;
//strData = strData.Substring(0, length);
//RaisedMessage(sokClient.RemoteEndPoint.ToString(), strData.Replace("\0", "<0>"));
string strData = Encoding.Default.GetString(arrMsgRec); // 将接受到的字节数据转化成字符串;
//strData = strData.Substring(0, length);
//RaisedMessage(sokClient.RemoteEndPoint.ToString(), strData.Replace("\0", "<0>"));
RaisedMessage(sokClient.RemoteEndPoint.ToString(), strData.Replace("\0", "."));
}
}
@@ -238,7 +205,7 @@ namespace HexcalMC.Hexcal
{
// TcpIpDfn.SongLiang_arrMsgRec = arrMsgRec; //510
string strData =
System.Text.Encoding.Default.GetString(arrMsgRec, 2,
Encoding.Default.GetString(arrMsgRec, 2,
arrMsgRec.Length - 2); // 将接受到的字节数据转化成字符串;
RaisedMessage(sokClient.RemoteEndPoint.ToString(), strData);
@@ -253,40 +220,42 @@ namespace HexcalMC.Hexcal
}
//删除客户端对象
void RemoveSocketClient(string strRemoteEndPoint)
private void RemoveSocketClient(string strRemoteEndPoint)
{
// 从通信套接字集合中 删除被中断连接的通信套接字;
DictSocket.Remove(strRemoteEndPoint);
_dictSocket.Remove(strRemoteEndPoint);
// 从通信线程集合中 删除被中断连接的通信线程对象;
DictThread.Remove(strRemoteEndPoint);
_dictThread.Remove(strRemoteEndPoint);
}
//发送消息
public void SendMessage(string strSocketKey, string strMsg)
{
byte[] arrMsg = System.Text.Encoding.Default.GetBytes(strMsg);
DictSocket[strSocketKey].Send(arrMsg);
byte[] arrMsg = Encoding.Default.GetBytes(strMsg);
_dictSocket[strSocketKey].Send(arrMsg);
}
public void SendMessage(string strSocketKey, byte[] arrMsg)
{
DictSocket[strSocketKey].Send(arrMsg);
_dictSocket[strSocketKey].Send(arrMsg);
}
/// <summary> 发送数据函数(字符串, 自动添加长度(byte格式))</summary>
/// <summary>
/// 发送数据函数(字符串, 自动添加长度(byte格式))
/// </summary>
public string SendMessage2(string strSocketKey, string strMsg)
{
try
{
if (DictSocket[strSocketKey].Connected)
if (_dictSocket[strSocketKey].Connected)
{
byte[] arrLength = new byte[2];
arrLength = BitConverter.GetBytes(Convert.ToInt16(strMsg.Length));
byte[] WriteBuffer = Encoding.Default.GetBytes(strMsg);
WriteBuffer = arrLength.Concat(WriteBuffer).ToArray();
byte[] writeBuffer = Encoding.Default.GetBytes(strMsg);
writeBuffer = arrLength.Concat(writeBuffer).ToArray();
DictSocket[strSocketKey].Send(WriteBuffer);
_dictSocket[strSocketKey].Send(writeBuffer);
return "";
}
@@ -300,8 +269,8 @@ namespace HexcalMC.Hexcal
public void SendMessageToAllClients(string strMsg)
{
byte[] arrMsg = System.Text.Encoding.Default.GetBytes(strMsg);
foreach (Socket soc in DictSocket.Values)
byte[] arrMsg = Encoding.Default.GetBytes(strMsg);
foreach (Socket soc in _dictSocket.Values)
{
soc.Send(arrMsg);
}
@@ -309,31 +278,29 @@ namespace HexcalMC.Hexcal
public void SendMessageToAllClients(byte[] arrMsg)
{
foreach (Socket soc in DictSocket.Values)
foreach (Socket soc in _dictSocket.Values)
{
soc.Send(arrMsg);
}
}
public delegate void EventHandler_RaisedStatus(EnumTcpIpServer Type, string Msg);
public event EventHandler_RaisedStatus OnRaisedStatus;
public event EventHandlerRaisedStatus OnRaisedStatus;
// 异步或同步触发自定义事件,并在目标控件是 Windows Forms 控件的情况下添加到目标控件的消息队列中。它主要的目的是使得自定义事件处理程序在UI线程上执行,以避免线程上的卡顿或UI更新问题。
private void RaisedStatus(EnumTcpIpServer ReturnType, string Msg)
private void RaisedStatus(EnumTcpIpServer returnType, string msg)
{
try
{
if (OnRaisedStatus != null)
{
if (OnRaisedStatus.Target is System.Windows.Forms.Control)
if (OnRaisedStatus.Target is Control)
{
Control targetForm = OnRaisedStatus.Target as System.Windows.Forms.Control;
targetForm.BeginInvoke(OnRaisedStatus, new object[] { ReturnType, Msg });
Control targetForm = OnRaisedStatus.Target as Control;
targetForm.BeginInvoke(OnRaisedStatus, returnType, msg);
}
else
{
OnRaisedStatus(ReturnType, Msg);
OnRaisedStatus(returnType, msg);
}
}
}
@@ -342,24 +309,22 @@ namespace HexcalMC.Hexcal
}
}
public delegate void EventHandler_RaisedMessage(string ClientIP, string Msg);
public event EventHandlerRaisedMessage OnRaisedMessage;
public event EventHandler_RaisedMessage OnRaisedMessage;
private void RaisedMessage(string ClientIP, string Msg)
private void RaisedMessage(string clientIp, string msg)
{
try
{
if (OnRaisedMessage != null)
{
if (OnRaisedMessage.Target is System.Windows.Forms.Control)
if (OnRaisedMessage.Target is Control)
{
Control targetForm = OnRaisedMessage.Target as System.Windows.Forms.Control;
targetForm.BeginInvoke(OnRaisedMessage, new object[] { ClientIP, Msg });
Control targetForm = OnRaisedMessage.Target as Control;
targetForm.BeginInvoke(OnRaisedMessage, clientIp, msg);
}
else
{
OnRaisedMessage(ClientIP, Msg);
OnRaisedMessage(clientIp, msg);
}
}
}
@@ -367,5 +332,35 @@ namespace HexcalMC.Hexcal
{
}
}
#region
private readonly Timer _serverTimer = new Timer();
private void ServerTimerLoop(object sender, EventArgs e)
{
_serverTimer.Interval = 20000; //监听timer的间隔
if (_dictSocket != null)
{
if (_dictSocket.Count != 0)
{
_dictSocket.Values.ToArray();
for (int i = _dictSocket.Values.ToArray().Length - 1; i >= 0; i--)
{
if (_dictSocket.Values.ToArray()[i]
.Poll(10, SelectMode.SelectRead)) //10毫秒,检查套接字状态, SelectMode 参数指定要监视的套接字的类别。
{
// DictSocket.Remove(DictSocket.Keys.ToArray()[i]);
RaisedStatus(EnumTcpIpServer.ConnectException,
"连接已断开:" + _dictSocket.Keys.ToArray()[i]); //刷新界面显示,触发一个连接异常状态枚举,并将消息传递为异常的状态
RemoveSocketClient(_dictSocket.Keys.ToArray()[i]);
}
}
}
}
}
#endregion
}
}
}