你的位置:首页 > ASP.net教程

[ASP.net教程]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);                    if (m_Client.Connected) m_Client.Disconnect(false);                    m_Client.Close();                    m_Client.Dispose();                    LogUtil.Log("客户端已失去连接,当前客户端数:" + m_ClientList.Count);                    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 XXPLClient.Service{  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 XXPLClient.Service{  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 XXPLClient.Service;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