using System; using System.Collections.Generic; using System.Net; using System.Net.Sockets; using System.Threading; using System.Windows.Forms; using System.Text; using HardwareConfig; using BaseLibRWFile; namespace BaseLibComm { public struct StNetworkPort { public int Index; public bool Enable; public string Name; public string IP; public string Port; public Socket[] ArrSocket; public bool[] ArrLinkStatus; public string[] ArrStrRecMsg; } public class SocketManager { public static SocketManager Ins { set; get; } = new SocketManager(); public static Dictionary DicSeverStruct { set; get; } = new Dictionary { }; public static Dictionary DicClientStruct { set; get; } = new Dictionary { }; public SocketManager() { } public Ini newIni; public static List listSocketAttisServer = new List(); public static List listSocketAttisClient = new List(); public void LoadServerClient() { listSocketAttisServer.Clear(); listSocketAttisClient.Clear(); newIni = new Ini(Application.StartupPath + "\\Vision\\Config\\Net.ini"); int iServerCount = Convert.ToInt32(newIni.ReadIni("Count", "服务器数量", "1")); int iClientCount = Convert.ToInt32(newIni.ReadIni("Count", "客户端数量", "1")); for (int i = 0; i < iServerCount; i++) { SocketAtti socketAtti = new SocketAtti { 编号 = i, 网口类型 = SocketTypeEnum.服务器, 网口名称 = newIni.ReadIni($"服务器{i}", "名称", $"服务器{i}"), Enable = Convert.ToBoolean(newIni.ReadIni($"服务器{i}", "Enable", "False")), IP = newIni.ReadIni($"服务器{i}", "IP", "127.0.0.1"), 端口号 = newIni.ReadIni($"服务器{i}", "端口号", "8000") }; listSocketAttisServer.Add(socketAtti); } for (int i = 0; i < iClientCount; i++) { SocketAtti socketAtti = new SocketAtti { 编号 = i, 网口类型 = SocketTypeEnum.客户端, 网口名称 = newIni.ReadIni($"客户端{i}", "名称", $"客户端{i}"), Enable = Convert.ToBoolean(newIni.ReadIni($"客户端{i}", "Enable", "False")), IP = newIni.ReadIni($"客户端{i}", "IP", "127.0.0.1"), 端口号 = newIni.ReadIni($"客户端{i}", "端口号", "8000") }; listSocketAttisClient.Add(socketAtti); } } public void LoadSocket() { LoadServerClient(); StNetworkPort st = new StNetworkPort(); foreach (var p in listSocketAttisServer)//var p in HardConfigManager.Ins.HardwareList { st.Index = p.编号; st.IP = p.IP; st.Name = p.网口名称; st.Port = p.端口号; st.ArrStrRecMsg = new string[20]; st.ArrLinkStatus = new bool[20]; st.ArrSocket = new Socket[20]; DicSeverStruct.Add(st.Name, st); } foreach (var p in listSocketAttisClient) { st.Index = p.编号; st.IP = p.IP; st.Name = p.网口名称; st.Port = p.端口号; st.ArrStrRecMsg = new string[1]; st.ArrLinkStatus = new bool[1]; st.ArrSocket = new Socket[1]; DicClientStruct.Add(st.Name, st); } #region MyRegion //if (p.Enable) //{ //switch (p.网口类型)//p.HardwareName //{ // SocketAtti sockethc = (SocketAtti)p; // st.Index = sockethc.编号; // st.IP = sockethc.IP; // st.Name = sockethc.网口名称; // st.Port = sockethc.端口号; // if (sockethc.网口类型==SocketTypeEnum.客户端) // { // st.ArrStrRecMsg = new string[1]; // st.ArrLinkStatus = new bool[1]; // st.ArrSocket = new Socket[1]; // DicClientStruct.Add(st.Name, st); // } // else if (sockethc.网口类型 == SocketTypeEnum.服务器) // { // st.ArrStrRecMsg = new string[20]; // st.ArrLinkStatus = new bool[20]; // st.ArrSocket = new Socket[20]; // DicClientStruct.Add(st.Name, st); // } // break; //default: // break; //} //} #endregion } public bool CreatSocket() { int ret = 0; foreach (var p in DicSeverStruct) { if (!p.Value.ArrLinkStatus[0] && p.Value.Name!="UIServer") { if (!CreateServer(p.Value)) { ret--; //return false; } } } try { foreach (var p in DicClientStruct) { if (!p.Value.ArrLinkStatus[0] && p.Value.Name != "UIClient") { if (!CreateClient(p.Value)) { ret--; //return false; } } } } catch (Exception ex) { MessageBox.Show("创建客户端错误 " + ex.Message); } if (ret == 0) { return true; } return false; } public bool CreateServer(StNetworkPort st) { try { if (st.ArrSocket[0] == null) { st.ArrSocket[0] = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); IPAddress address = IPAddress.Parse(st.IP); IPEndPoint point = new IPEndPoint(address, int.Parse(st.Port)); st.ArrSocket[0].Bind(point); st.ArrSocket[0].Listen(20); st.ArrLinkStatus[0] = true; if (!DicSeverStruct.ContainsKey($"{st.Name}")) { //DicSeverStruct.Remove($"{st.Name}"); DicSeverStruct.Add($"{st.Name}", st); } Thread ServerLisenThread = new Thread(new ParameterizedThreadStart(ServerLisening)); ServerLisenThread.IsBackground = true; ServerLisenThread.Start($"{st.Name}"); return true; } else { MessageBox.Show($"服务器{st.IP}:{st.Port}已创建\r\nServer {st.IP}:{st.Port} created"); return false; } } catch (Exception ex) { MessageBox.Show($"创建服务器{st.IP}:{st.Port}失败\r\nCreate {st.IP}:{st.Port} failed\r\n{ex.Message}"); return false; } } private void ServerLisening(object structName) { string stName = structName as string; int indexClient = 0; Socket s = null; while (true) { try { indexClient++; if (indexClient > 19) { indexClient = 1; } if (DicSeverStruct[stName].ArrSocket[indexClient] == null) { DicSeverStruct[stName].ArrSocket[indexClient] = DicSeverStruct[stName].ArrSocket[0].Accept(); s = DicSeverStruct[stName].ArrSocket[indexClient]; } } catch (Exception ex) { DicSeverStruct[stName].ArrLinkStatus[0] = false; DicSeverStruct[stName].ArrStrRecMsg[0] = string.Empty; DicSeverStruct[stName].ArrSocket[0] = null; MessageBox.Show($"监听服务器{DicSeverStruct[stName].IP}:{DicSeverStruct[stName].Port}出错" + $"\r\nLisening server{DicSeverStruct[stName].IP}:{DicSeverStruct[stName].Port} error\r\n{ex.Message}"); break; } if (s != null) { IPAddress clientIP = (s.RemoteEndPoint as IPEndPoint).Address; int clientPort = (s.RemoteEndPoint as IPEndPoint).Port; string sendmsg = $"连接服务端成功!本地IP:{clientIP},本地端口:{clientPort}"; byte[] arrSendMsg = Encoding.Default.GetBytes(sendmsg); s.Send(arrSendMsg); string remoteEndPoint = $"{s.LocalEndPoint}_{s.RemoteEndPoint}"; IPEndPoint netpoint = s.RemoteEndPoint as IPEndPoint; Thread thread = new Thread(new ParameterizedThreadStart(ServerReceive)); thread.IsBackground = true; thread.Start($"{stName},{indexClient}"); DicSeverStruct[stName].ArrLinkStatus[indexClient] = true; } Thread.Sleep(1); } } private void ServerReceive(object structName) { string stNameI = structName as string; string stName = stNameI.Split(',')[0]; int indexClient = Convert.ToInt32(stNameI.Split(',')[1]); Socket s = DicSeverStruct[stName].ArrSocket[indexClient]; int keepAlive = -1744830460; // SIO_KEEPALIVE_VALS //KeepAlive的时间为20秒,检查间隔为2秒,20秒的16进制表示是4e20,2秒的16进制表示是07d0 byte[] inValue = new byte[] { 1, 0, 0, 0, 0x20, 0x4e, 0, 0, 0xd0, 0x07, 0, 0 }; s.IOControl(keepAlive, inValue, null); while (true) { try { if (CheckConnectStatus(s)) { if (s.Available != 0) { byte[] recBytes = new byte[1024 * 8]; int length = 1; while (length > 0) { length = s.Receive(recBytes); DicSeverStruct[stName].ArrStrRecMsg[indexClient] += Encoding.Default.GetString(recBytes, 0, length); } } } else { DicSeverStruct[stName].ArrLinkStatus[indexClient] = false; DicSeverStruct[stName].ArrStrRecMsg[indexClient] = string.Empty; DicSeverStruct[stName].ArrSocket[indexClient] = null; //SeverStructDic.Remove(stName); //MessageBox.Show($"客户端{stName}已经中断连接\r\nClient{stName} disconnect"); string str = $"客户端{stName}已经中断连接:"; Msg.Show($"{str}\r\n", $"{str}\r\nThe client has disconnected:\r\n", $"{str}\r\nKhách hàng đã ngắt kết nối:\r\n","Error", msgicon: MessageBoxIcon.Error); break; } } catch (Exception ex) { DicSeverStruct[stName].ArrLinkStatus[indexClient] = false; DicSeverStruct[stName].ArrStrRecMsg[indexClient] = string.Empty; DicSeverStruct[stName].ArrSocket[indexClient] = null; //SeverStructDic.Remove(stName); //MessageBox.Show($"客户端{stName}已经中断连接\r\nClient{stName} disconnect\r\n{ex.Message}"); string str = $"客户端{stName}已经中断连接:"; Msg.Show($"{str}\r\n{ex}", $"{str}\r\nThe client has disconnected:\r\n{ex}", $"{str}\r\nKhách hàng đã ngắt kết nối:\r\n{ex}","Error", msgicon: MessageBoxIcon.Error); break; } Thread.Sleep(1); } } public bool CreateClient(StNetworkPort st) { try { IPAddress IP1 = IPAddress.Parse(st.IP); IPEndPoint remoteEP = new IPEndPoint(IP1, int.Parse(st.Port)); st.ArrSocket[0] = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); st.ArrSocket[0].Connect(remoteEP); st.ArrLinkStatus[0] = true; if (!DicClientStruct.ContainsKey($"{st.Name}")) { //DicClientStruct.Remove($"{st.Name}"); DicClientStruct.Add($"{st.Name}", st); } Thread ClientReceiveThread = new Thread(new ParameterizedThreadStart(ReceiveData)); ClientReceiveThread.IsBackground = true; ClientReceiveThread.Start($"{st.Name}"); return true; } catch (Exception ex) { st.ArrLinkStatus[0] = false; if (!DicClientStruct.ContainsKey($"{st.Name}")) { //DicClientStruct.Remove($"{st.Name}"); DicClientStruct.Add($"{st.Name}", st); } string str = $"{st.Name}连接服务器{st.IP}:{st.Port}失败"; Msg.Show($"{str}\r\n{ex}", $"{str}\r\nFailed to link to server:\r\n{ex}", $"{str}\r\nkết nối thất bại:\r\n{ex}", "Error", msgicon: MessageBoxIcon.Error); //MessageBox.Show($"{st.Name}连接服务器{st.IP}:{st.Port}失败\r\n{st.Name}Connect sever {st.IP}:{st.Port} failed\r\n{ex.Message}"); return false; } } public void ReceiveData(object structName) { string stName = structName as string; Socket s = DicClientStruct[stName].ArrSocket[0]; while (true) { try { if (CheckConnectStatus(s)) { if (s.Available != 0) { byte[] recBytes = new byte[1024 * 8]; int length = 1; while (s.Available != 0) { length = s.Receive(recBytes); DicClientStruct[stName].ArrStrRecMsg[0] += Encoding.Default.GetString(recBytes, 0, length); } } } else { DicClientStruct[stName].ArrLinkStatus[0] = false; DicClientStruct[stName].ArrStrRecMsg[0] = string.Empty; DicClientStruct[stName].ArrSocket[0] = null; //ClientStructDic.Remove(stName); //MessageBox.Show($"{stName}已经中断连接\r\n{stName} disconnect"); string str = $"{stName}客户端已经中断连接:"; Msg.Show($"{str}\r\n", $"{str}\r\nThe client has disconnected:\r\n", $"{str}\r\nKhách hàng đã ngắt kết nối:\r\n","Error", msgicon: MessageBoxIcon.Error); break; } } catch (Exception ex) { DicClientStruct[stName].ArrLinkStatus[0] = false; DicClientStruct[stName].ArrStrRecMsg[0] = string.Empty; DicClientStruct[stName].ArrSocket[0] = null; //ClientStructDic.Remove(stName); //MessageBox.Show($"{stName}已经中断连接\r\n{stName} disconnect\r\n{ex.Message}"); string str = $"{stName}客户端已经中断连接"; Msg.Show($"{str}\r\n{ex}", $"{str}\r\nThe client has disconnected:\r\n{ex}", $"{str}\r\nKhách hàng đã ngắt kết nối:\r\n{ex}","Error", msgicon: MessageBoxIcon.Error); break; } Thread.Sleep(1); } } public bool SendData(Socket s, string sendStr, bool Is16) { try { if (CheckConnectStatus(s)) { byte[] sendBytes; if (Is16) { sendBytes = HexStrTobyte(sendStr); } else { sendBytes = Encoding.UTF8.GetBytes(sendStr); } int testNum = s.Send(sendBytes); return true; } return false; } catch (Exception ex) { MessageBox.Show(ex.Message); return false; } } private byte[] HexStrTobyte(string hexString) { hexString = hexString.Replace(" ", ""); if (hexString.Length % 2 != 0) hexString += " "; byte[] returnBytes = new byte[hexString.Length / 2]; for (int i = 0; i < returnBytes.Length; i++) returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2).Trim(), 16); return returnBytes; } // 字节数组转16进制字符串 public string byteToHexStr(byte[] bytes) { string returnStr = ""; if (bytes != null) { for (int i = 0; i < bytes.Length; i++) { returnStr += bytes[i].ToString("X2");//ToString("X2") 为C#中的字符串格式控制符 } } return returnStr; } public byte[] HexStringToBytes(string hs) { string[] strArr = hs.Trim().Split(' '); byte[] b = new byte[strArr.Length]; //逐个字符变为16进制字节数据 for (int i = 0; i < strArr.Length; i++) { b[i] = Convert.ToByte(strArr[i], 16); } //按照指定编码将字节数组变为字符串 return b; } public string ReceiveSocketData(Socket s) { if (CheckConnectStatus(s)) { string strTemp = ""; if (!(s.Available == 0)) { byte[] recBytes = new byte[s.Available]; int lengh = s.Receive(recBytes); strTemp = Encoding.Default.GetString(recBytes, 0, lengh); } if (strTemp.Length > 0) { return strTemp; } } return ""; } /// /// 增加链接次数 次数很多未链接 则跳出循环 /// /// public string ByteToString(byte[] recBytes) { string strTemp = ""; for (int i = 9; i < 13; i++) { strTemp += recBytes[i].ToString("X2"); //((char)recBytes[i]).ToString();// } if (!string.IsNullOrEmpty(strTemp)) { strTemp = _16ToA(strTemp); string alpha = ((char)int.Parse(strTemp)).ToString(); return alpha; } return null; } /// /// 16进制字符串转换为Ascii字符串 /// 有些不需要的字符可以加判断清除 /// /// 16进制字符串 /// Ascii字符串 public string _16ToA(string InHex) { int a = InHex.Length; string str1 = ""; string str = ""; byte[] MMid = new byte[a]; for (int z = 0; z < a / 2; z++) { str1 = InHex.Substring(z * 2, 2); MMid[z] = Convert.ToByte(str1, 16); if (MMid[z] < 0x1f)//判断清除不可见字符 { MMid[z] = 0x00; } string aa = MMid[z].ToString("X2"); } str = Encoding.ASCII.GetString(MMid); //Console.Write(str); return str; } public bool CheckConnectStatus(Socket s) //检查连接状态 { if (s == null) { return false; } bool ConnectStatus = !(s.Poll(1000, SelectMode.SelectRead) && s.Available == 0 || !s.Connected); return ConnectStatus; } public void SocketClose(Socket socket) { if (socket == null) return; //if (!socket.Connected) // return; try { socket.Shutdown(SocketShutdown.Both); } catch { } try { socket.Close(); } catch { } } } }