程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> C# .NET Socket封裝,

C# .NET Socket封裝,

編輯:C#入門知識

C# .NET Socket封裝,


    Socket封裝,支持多客戶端。

    封裝所要達到的效果,是可以像下面這樣使用Socket和服務端通信,調用服務端的方法:

DemoService demoService = new DemoService();
DemoService2 demoService2 = new DemoService2();
string result = demoService.Test("測試DemoService", 1);
demoService.Test2("測試DemoService", 1);
string result2 = demoService2.RunTest("測試DemoService2", 2);

一、數據結構:

CmdType:

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace DataStruct { /// <summary> /// cmd類型 /// </summary> public enum CmdType { /// <summary> /// 執行方法 /// </summary> RunFunction = 1, /// <summary> /// 心跳 /// </summary> Heartbeat = 2 } } View Code

SocketData:

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace DataStruct { /// <summary> /// Socket數據 /// </summary> [Serializable] public class SocketData { /// <summary> /// 命令類型 /// </summary> public CmdType cmdType { get; set; } /// <summary> /// 類名 /// </summary> public string className { get; set; } /// <summary> /// 方法名 /// </summary> public string functionName { get; set; } /// <summary> /// 方法參數 /// </summary> public object[] funParam { get; set; } } } View Code

FunctionUtil(根據SocketData執行服務端的方法):

using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; namespace DataStruct.Utils { /// <summary> /// 執行方法 /// </summary> public class FunctionUtil { /// <summary> /// 執行方法 /// </summary> public static object RunFunction(string applicationPath, SocketData socketData) { Assembly assembly = Assembly.LoadFile(Path.Combine(applicationPath, "DataService.dll")); object obj = assembly.CreateInstance("DataService." + socketData.className); Type type = obj.GetType(); return type.GetMethod(socketData.functionName).Invoke(obj, socketData.funParam); } } } View Code

二、服務端Socket通信:

using System; using System.Collections.Generic; using System.ComponentModel; using System.Configuration; using System.Data; using System.Drawing; using System.IO; using System.Linq; using System.Net; using System.Net.Sockets; using System.Runtime.Serialization.Formatters.Binary; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; using Common.Utils; using CommonDll; using DataService; using DataStruct; using DataStruct.Utils; using Newtonsoft.Json; namespace XXPLServer { public partial class Form1 : Form { #region 變量 private Socket m_ServerSocket; private List<Socket> m_ClientList = new List<Socket>(); #endregion #region Form1構造函數 public Form1() { InitializeComponent(); } #endregion #region Form1_Load private void Form1_Load(object sender, EventArgs e) { } #endregion #region 啟動服務 private void btnStartServer_Click(object sender, EventArgs e) { try { btnStartServer.Enabled = false; btnStopServer.Enabled = true; int port = Convert.ToInt32(ConfigurationManager.AppSettings["ServerPort"]); IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Any, port); m_ServerSocket = new Socket(ipEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); m_ServerSocket.Bind(ipEndPoint); m_ServerSocket.Listen(10); new Thread(new ThreadStart(delegate() { while (true) { Socket m_Client; try { m_Client = m_ServerSocket.Accept(); m_Client.SendTimeout = 20000; m_Client.ReceiveTimeout = 20000; m_ClientList.Add(m_Client); LogUtil.Log("監聽到新的客戶端,當前客戶端數:" + m_ClientList.Count); } catch { break; } DateTime lastHeartbeat = DateTime.Now; new Thread(new ThreadStart(delegate() { try { while (true) { byte[] inBuffer = new byte[m_Client.ReceiveBufferSize]; int receiveCount; try { receiveCount = m_Client.Receive(inBuffer, m_Client.ReceiveBufferSize, SocketFlags.None);//如果接收的消息為空 阻塞 當前循環 } catch { break; } if (receiveCount != 0) { SocketData data = (SocketData)SerializeUtil.Deserialize(inBuffer); if (data.cmdType != CmdType.Heartbeat) { object obj = FunctionUtil.RunFunction(Application.StartupPath, data); m_Client.Send(SerializeUtil.Serialize(obj)); LogUtil.Log("接收客戶端數據,並向客戶端返回數據"); } else { lastHeartbeat = DateTime.Now; } } else { m_ClientList.Remove(m_Client); LogUtil.Log("客戶端正常關閉,當前客戶端數:" + m_ClientList.Count); if (m_Client.Connected) m_Client.Disconnect(false); m_Client.Close(); m_Client.Dispose(); break; } } } catch (Exception ex) { LogUtil.LogError(ex.Message + "\r\n" + ex.StackTrace); } })).Start(); //檢測客戶端 new Thread(new ThreadStart(delegate() { try { while (true) { DateTime now = DateTime.Now; if (now.Subtract(lastHeartbeat).TotalSeconds > 20) { m_ClientList.Remove(m_Client); LogUtil.Log("客戶端已失去連接,當前客戶端數:" + m_ClientList.Count); if (m_Client.Connected) m_Client.Disconnect(false); m_Client.Close(); m_Client.Dispose(); break; } Thread.Sleep(500); } } catch (Exception ex) { LogUtil.LogError("檢測客戶端出錯:" + ex.Message + "\r\n" + ex.StackTrace); } })).Start(); } })).Start(); LogUtil.Log("服務已啟動"); } catch (Exception ex) { LogUtil.LogError("啟動服務出錯:" + ex.Message + "\r\n" + ex.StackTrace); } } #endregion #region 停止服務 private void btnStopServer_Click(object sender, EventArgs e) { btnStopServer.Enabled = false; btnStartServer.Enabled = true; foreach (Socket socket in m_ClientList) { if (socket.Connected) socket.Disconnect(false); socket.Close(); socket.Dispose(); } if (m_ServerSocket != null) { if (m_ServerSocket.Connected) m_ServerSocket.Disconnect(false); m_ServerSocket.Close(); m_ServerSocket.Dispose(); } LogUtil.Log("服務已停止"); } #endregion #region Form1_FormClosing private void Form1_FormClosing(object sender, FormClosingEventArgs e) { foreach (Socket socket in m_ClientList) { if (socket.Connected) socket.Disconnect(false); socket.Close(); socket.Dispose(); } if (m_ServerSocket != null) { if (m_ServerSocket.Connected) m_ServerSocket.Disconnect(false); m_ServerSocket.Close(); m_ServerSocket.Dispose(); } LogUtil.Log("服務已停止"); } #endregion } } View Code

三、服務端的服務接口類:

DemoService:

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace DataService { /// <summary> /// socket服務 /// </summary> public class DemoService { public string Test(string str, int n) { return str + ":" + n; } public void Test2(string str, int n) { string s = str + n; } } } View Code

DemoService2:

using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace DataService { public class DemoService2 { public string RunTest(string str, int n) { return str + ":" + n; } } } View Code

三、客戶端Socket通信代碼:

using System; using System.Collections.Generic; using System.Configuration; using System.Linq; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; using DataStruct; using CommonDll; namespace Common.Utils { /// <summary> /// 服務 /// </summary> public class ServiceUtil { public static Socket clientSocket; public static object _lock = new object(); /// <summary> /// 連接服務器 /// </summary> public static void ConnectServer() { if (clientSocket == null || !clientSocket.Connected) { if (clientSocket != null) { clientSocket.Close(); clientSocket.Dispose(); } string ip = ConfigurationManager.AppSettings["ServerIP"]; IPEndPoint ipep = new IPEndPoint(IPAddress.Parse(ip), 3001); clientSocket = new Socket(ipep.AddressFamily, SocketType.Stream, ProtocolType.Tcp); clientSocket.SendTimeout = 20000; clientSocket.ReceiveTimeout = 20000; clientSocket.Connect(ipep); } } /// <summary> /// 請求 /// </summary> public static object Request(SocketData data) { lock (_lock) { try { ConnectServer(); clientSocket.Send(SerializeUtil.Serialize(data)); byte[] inBuffer = new byte[clientSocket.ReceiveBufferSize]; int count = clientSocket.Receive(inBuffer, clientSocket.ReceiveBufferSize, SocketFlags.None);//如果接收的消息為空 阻塞 當前循環 if (count > 0) { return SerializeUtil.Deserialize(inBuffer); } else { if (clientSocket.Connected) clientSocket.Disconnect(false); clientSocket.Close(); clientSocket.Dispose(); return Request(data); } } catch (Exception ex) { if (clientSocket.Connected) clientSocket.Disconnect(false); LogUtil.LogError(ex.Message); throw ex; } } } /// <summary> /// 請求 /// </summary> public static object Request(string className, string methodName, object[] param) { SocketData data = new SocketData(); data.className = className; data.functionName = methodName; data.funParam = param; return ServiceUtil.Request(data); } } } View Code

六、客戶端接口類代碼:

DemoService:

using System; using System.Collections.Generic; using System.Linq; using System.Text; using DataStruct; using Common.Utils; using System.Reflection; namespace ClientService { public class DemoService { public string Test(string str, int n) { object result = ServiceUtil.Request(this.GetType().Name, MethodBase.GetCurrentMethod().Name, new object[] { str, n }); return result.ToString(); } public void Test2(string str, int n) { object result = ServiceUtil.Request(this.GetType().Name, MethodBase.GetCurrentMethod().Name, new object[] { str, n }); } } } View Code

DemoService2:

using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text; using Common.Utils; using DataStruct; namespace ClientService { public class DemoService2 { public string RunTest(string str, int n) { object result = ServiceUtil.Request(this.GetType().Name, MethodBase.GetCurrentMethod().Name, new object[] { str, n }); return result.ToString(); } } } View Code

六:客戶端測試代碼:

using System; using System.Collections.Generic; using System.ComponentModel; using System.Configuration; using System.Data; using System.Drawing; using System.Linq; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; using Common.Utils; using CommonDll; using DataStruct; using ClientService; namespace XXPLClient { public partial class Form1 : Form { #region 變量 private System.Timers.Timer m_timer; #endregion #region Form1構造函數 public Form1() { InitializeComponent(); } #endregion #region Form1_Load private void Form1_Load(object sender, EventArgs e) { try { //連接服務器 ServiceUtil.ConnectServer(); } catch (Exception ex) { MessageBox.Show("連接服務器失敗:" + ex.Message); } //心跳包 m_timer = new System.Timers.Timer(); m_timer.Interval = 5000; m_timer.Elapsed += new System.Timers.ElapsedEventHandler((obj, eea) => { try { lock (ServiceUtil._lock) { SocketData data = new SocketData(); data.cmdType = CmdType.Heartbeat; ServiceUtil.ConnectServer(); ServiceUtil.clientSocket.Send(SerializeUtil.Serialize(data)); } } catch (Exception ex) { LogUtil.LogError("向服務器發送心跳包出錯:" + ex.Message); } }); m_timer.Start(); } #endregion private void btnTest_Click(object sender, EventArgs e) { try { DemoService demoService = new DemoService(); DemoService2 demoService2 = new DemoService2(); MessageBox.Show(demoService.Test("測試DemoService", 1) + "\r\n" + demoService2.RunTest("測試DemoService2", 2)); } catch (Exception ex) { LogUtil.LogError(ex.Message); MessageBox.Show(ex.Message); } } private void Form1_FormClosing(object sender, FormClosingEventArgs e) { m_timer.Stop(); if (ServiceUtil.clientSocket != null) { if (ServiceUtil.clientSocket.Connected) ServiceUtil.clientSocket.Disconnect(false); ServiceUtil.clientSocket.Close(); ServiceUtil.clientSocket.Dispose(); } } } } View Code

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved