Socket封装,支持多客户端,支持大文件传输,支持多线程并发,对较大的Socket包进行分块传输。
封装所要达到的效果,是可以像下面这样使用Socket和服务端通信,调用服务端的方法,让你在使用Socket的时候,感觉不到Socket的存在,就像是调用本地方法一样,并且支持ref参数和out参数:
DemoService demoService = new DemoService(); DemoService2 demoService2 = DemoService2(); string result = demoService.Test("测试DemoService",1); demoService.Test2(); string result2 = demoService2.RunTest(测试DemoService22);
一、数据结构:
CmdType:
using System; System.Collections.Generic; System.Linq; System.Text; System.Threading.Tasks; namespace DataStruct { /// <summary> /// cmd类型 </summary> public enum CmdType { <summary> 执行方法 </summary> RunFunction = , 心跳 </summary> Heartbeat = 2 } }
SocketData:
Socket数据 </summary> [Serializable] class SocketData { 命令类型 </summary> public CmdType cmdType { get; set; } 类名 string className { 方法名 string functionName { 方法参数 object[] funParam { ; } } }
SocketResult:
FunctionUtil(根据SocketData执行服务端的方法):
System.IO; System.Reflection; DataStruct.Utils { 执行方法 FunctionUtil { static object RunFunction(string applicationPath,SocketData socketData) { Assembly assembly = Assembly.LoadFile(Path.Combine(applicationPath,1)">DataService.dll")); object classObj = assembly.CreateInstance(DataService." + socketData.className); Type type = classObj.GetType(); MethodInfo methodInfo = type.getmethod(socketData.functionName); ParameterInfo[] parameterInfoArr = methodInfo.GetParameters(); object result = methodInfo.Invoke(classObj,socketData.funParam); SocketResult socketResult = SocketResult(); socketResult.returnValue = result; socketResult.param = new object[socketData.funParam.Length]; paramObj; for (int i = 0; i < parameterInfoArr.Length; i++) { paramObj = socketData.funParam[i]; if (parameterInfoArr[i].ParameterType.IsByRef || parameterInfoArr[i].IsOut) { socketResult.param[i] = paramObj; } else { socketResult.param[i] = null; } } return socketResult; } } }
二、Socket通信封装:
System.Configuration; System.Net; System.Net.sockets; System.Threading; DataStruct.Utils; Socket封装 SocketHelper { #region 变量 private object _lockSend = (); static Socket serverSocket; Socket clientSocket; static List<Socket> clientList = new List<Socket> System.Timers.Timer heartbeatTimer; #endregion #region 启动服务 启动服务 void StartServer() { try { int port = Convert.ToInt32(ConfigurationManager.AppSettings[ServerPort]); IPEndPoint ipEndPoint = IPEndPoint(IPAddress.Any,port); serverSocket = Socket(ipEndPoint.AddressFamily,SocketType.Stream,ProtocolType.Tcp); serverSocket.Bind(ipEndPoint); serverSocket.Listen(10); new Thread(new ThreadStart(delegate() { while (true) { Socket m_Client; { m_Client = serverSocket.Accept(); m_Client.SendTimeout = 20000; m_Client.ReceiveTimeout = ; m_Client.SendBufferSize = 10240; m_Client.ReceiveBufferSize = ; clientList.Add(m_Client); LogUtil.Log(监听到新的客户端,当前客户端数: clientList.Count); } catch { break; } DateTime lastHeartbeat = DateTime.Now; () { { ) { byte[] receiveByteArr = ; { receiveByteArr = Receive(m_Client); } ; } if (receiveByteArr != ) { SocketData data = (SocketData)SerializeUtil.Deserialize(receiveByteArr); if (data.cmdType != CmdType.Heartbeat) { object obj = ; { obj = FunctionUtil.RunFunction(System.Windows.Forms.Application.StartupPath,data); } catch (Exception ex) { LogUtil.LogError(执行方法出错:" + ex.Message + \r\n ex.StackTrace); Send(m_Client,SerializeUtil.Serialize(error:执行服务端方法出错)); } Send(m_Client,SerializeUtil.Serialize(obj)); LogUtil.Log(接收客户端数据,并向客户端返回数据); } { lastHeartbeat = DateTime.Now; LogUtil.Log(收到心跳包,客户端连接正常); } } { clientList.Remove(m_Client); LogUtil.Log(客户端正常关闭,当前客户端数: clientList.Count); if (m_Client.Connected) m_Client.disconnect(false); m_Client.Close(); m_Client.dispose(); ; } } } (Exception ex) { LogUtil.LogError(ex.Message + ex.StackTrace); { Send(m_Client,1)">error: ex.Message)); } { } } })).Start(); //检测客户端 ) { DateTime Now = DateTime.Now; if (Now.Subtract(lastHeartbeat).TotalSeconds > 300) { clientList.Remove(m_Client); LogUtil.Log(客户端已失去连接,当前客户端数:; } Thread.Sleep(500); } } (Exception ex) { LogUtil.LogError(检测客户端出错: ex.StackTrace); } })).Start(); } })).Start(); LogUtil.Log(服务已启动); } (Exception ex) { LogUtil.LogError(启动服务出错: ex.StackTrace); } } #region 停止服务 停止服务 StopServer() { foreach (Socket socket in clientList) { if (socket.Connected) socket.disconnect(); socket.Close(); socket.dispose(); } clientList.Clear(); if (serverSocket != ) { if (serverSocket.Connected) serverSocket.disconnect(); serverSocket.Close(); serverSocket.dispose(); } LogUtil.Log(服务已停止停止服务出错:#region 连接服务器 连接服务器 ConnectServer() { if (clientSocket == null || !clientSocket.Connected) { if (clientSocket != ) { clientSocket.Close(); clientSocket.dispose(); } string ip = ConfigurationManager.AppSettings[ServerIP]; ]); IPEndPoint ipep = IPEndPoint(IPAddress.Parse(ip),port); clientSocket = Socket(ipep.AddressFamily,ProtocolType.Tcp); clientSocket.SendTimeout = ; clientSocket.ReceiveTimeout = ; clientSocket.SendBufferSize = ; clientSocket.ReceiveBufferSize = ; clientSocket.Connect(ipep); LogUtil.Log(已连接服务器); } } 连接服务器失败: ex.Message); } } #region 断开服务器 断开服务器 disconnectServer() { if (clientSocket.Connected) clientSocket.disconnect(); clientSocket.Close(); clientSocket.dispose(); } LogUtil.Log(已断开服务器断开服务器失败:#region 心跳 StartHeartbeat() { heartbeatTimer = System.Timers.Timer(); heartbeatTimer.Interval = 5000; heartbeatTimer.Elapsed += new System.Timers.ElapsedEventHandler((obj,eea) => { SocketData data = SocketData(); data.cmdType = CmdType.Heartbeat; Send(clientSocket,SerializeUtil.Serialize(data)); } (Exception ex) { LogUtil.LogError(向服务器发送心跳包出错: ex.Message); } }); heartbeatTimer.Start(); } #region 停止心跳 StopHeartbeat() { heartbeatTimer.Stop(); } #region Send Send void Send(Socket socket,byte[] data) { lock (_lockSend) { byte[] lenArr = BitConverter.GetBytes(data.Length); int sendTotal = 0; while (sendTotal < lenArr.Length) { int sendOnce = socket.Send(lenArr,sendTotal,lenArr.Length - sendTotal,SocketFlags.None); sendTotal += sendOnce; Thread.Sleep(); } Thread.Sleep(); int block = int count = (data.Length - 1) / block + 0; i < count; i++int currentBlock = block; if (i == count - ) { currentBlock = data.Length - block * i; } sendTotal = ; currentBlock) { int sendOnce = socket.Send(data,i * block + sendTotal,currentBlock - sendOnce; Thread.Sleep(); } Thread.Sleep(); } } } #region Receive Receive [] Receive(Socket socket) { (socket) { { 4byte[] buffer = [block]; int receiveCount = socket.Receive(buffer,block,SocketFlags.None); if (receiveCount == ) { return ; } { while (receiveCount < block) { int revCount = socket.Receive(buffer,receiveCount,buffer.Length - receiveCount,SocketFlags.None); receiveCount += revCount; Thread.Sleep(); } int dataLength = BitConverter.ToInt32(buffer,1)">); block = ; receiveCount = ; byte[] result = [dataLength]; dataLength) { int revCount = socket.Receive(result,result.Length - { SerializeUtil.Deserialize(result); } (Exception ex) { LogUtil.LogError(数据检验失败!); string aa = ex.Message; } result; } } 接收数据出错: ex.StackTrace); ; } } } #region IsZero IsZero bool IsZero(bool bl = ; foreach (byte b data) { if (b != ; } } LogUtil.LogError(接收的字节数组内容全是0); bl; } #region 请求 请求 Request(SocketData data) { { ConnectServer(); Send(clientSocket,SerializeUtil.Serialize(data)); ; receiveByteArr = Receive(clientSocket); SerializeUtil.Deserialize(receiveByteArr); if (result.GetType() == typeof(string) && result.ToString().IndexOf(") == string errMsg = result.ToString().Split(':')[]; LogUtil.LogError(errMsg); throw Exception(errMsg); } result; } ); clientSocket.Close(); clientSocket.dispose(); Request(data); } } (Exception ex) { ); LogUtil.LogError(ex.Message); throw ex; } } #region Request 请求 object Request(string className,1)">string methodName,1)">[] param) { SocketData data = SocketData(); data.className = className; data.functionName = methodName; data.funParam = param; Request(data); } #endregion } }
三、服务端的服务接口类:
DemoService:
System.Threading.Tasks; DAL; Models; DataService { socket服务 DemoService { public List<BS_NoticeType_ext> GetList(ref PagerModel pager,1)">out str) { NoticeTypeDal noticeTypeDal = NoticeTypeDal(); str = 测试123return noticeTypeDal.GetList(ref pager); } string Test(string str,1)">int n) { return str + : n; } void Test2(string s = str +void UploadFile(string fileName,1)">byte[] fileData,1)"> index) { string path = @"C:\Documents and Settings\Administrator\桌面\XXPLServer\files\string path = @"D:\_临时文件\文件\"; string path = @"C:\Users\Administrator\Desktop\suxtest\file\"; string path = @"C:\Documents and Settings\Administrator\桌面\Server\上传文件\"; if (index == ) { using (FileStream fs = new FileStream(path + fileName,FileMode.Create,FileAccess.Write)) { fs.Write(fileData,fileData.Length); fs.Close(); } } View Code
DemoService2:
DataService { DemoService2 { string RunTest( n; } } }
四、客户端接口类代码:
DemoService:
DataStruct; Common.Utils; ClientService { str) { SocketResult result = (SocketResult)ServiceUtil.Request(this.GetType().Name,MethodBase.GetCurrentMethod().Name,object[] { pager,1)"> }); pager = (PagerModel)result.param[]; str = (string)result.param[]; return (List<BS_NoticeType_ext>)result.returnValue; } n) { SocketResult result = (SocketResult)ServiceUtil.Request([] { str,n }); result.returnValue.ToString(); } bool UploadFile( { ServiceUtil.Request([] { fileName,fileData,index }); ; } ; } } } }
DemoService2:
DataStruct; result.returnValue.ToString(); } } }
五:服务端启动服务:
System.ComponentModel; System.Data; System.Drawing; System.Runtime.Serialization.Formatters.Binary; System.Windows.Forms; DataStruct.Utils; Newtonsoft.Json; XXPLServer { partial Form1 : Form { #region Form1构造函数 public Form1() { InitializeComponent(); } #region Form1_Load void Form1_Load( sender,EventArgs e) { } #region 启动服务 void btnStartServer_Click(; btnStartServer.Enabled = ; SocketHelper.StartServer(); } #region 停止服务 void btnStopServer_Click(; SocketHelper.StopServer(); } #region Form1_FormClosing void Form1_FormClosing(stem.Environment.Exit(); } } }
六:客户端测试代码:
CommonDll; ClientService; System.Diagnostics; XXPLClient { 连接服务器 SocketHelper.StartHeartbeat(); 心跳 } disconnectServer(); SocketHelper.StopHeartbeat(); System.Environment.Exit(void btnTest_Click(0; i < 1; i++new ParameterizedThreadStart((obj) =>int j = 0; j < 1; j++) { DemoService demoService = DemoService(); DemoService2 demoService2 = DemoService2(); string str = demoService.Test(1) + " + demoService2.RunTest(); MessageBox.Show(str); } } (Exception ex) { LogUtil.LogError(ex.Message); MessageBox.Show(ex.Message); } })).Start(); } } void btnUpload_Click(if (openFileDialog1.ShowDialog() == DialogResult.OK) { 1048576byte[] bArr = [block]; fileName; FileStream(openFileDialog1.FileName,FileMode.Open,FileAccess.Read)) { fileName = Path.GetFileName(fs.Name); long count = (fs.Length - ; DemoService demoService = DemoService(); ) { if (i != count - ) { fs.Read(bArr,bArr.Length); } { int len = (int)(fs.Length - block * i); bArr = [len]; fs.Read(bArr,1)">bool bl = demoService.UploadFile(fileName,bArr,i + ); while (!bl) { bl = demoService.UploadFile(fileName,1)">); LogUtil.LogError(发生错误,重发); Thread.Sleep(20); } Thread.Sleep(); } fs.Close(); } MessageBox.Show(成功); })).Start(); } (Exception ex) { MessageBox.Show(ex.Message); } } } void button1_Click( { DemoService demoService = DemoService(); PagerModel pager = PagerModel(); pager.page = ; pager.rows = str; List<BS_NoticeType_ext> list = demoService.GetList(ref pager,1)">out str); MessageBox.Show(string.Format(数据总条数:{0}\r\n页数:{1}\r\nout参数值:{2}\r\n第一条数据:{3}].name)); } string ss = ex.Message; } } } }
index) { ; string path = @"D:\_临时文件\文件\"; string path = @"C:\Users\Administrator\Desktop\suxtest\file\"; string path = @"C:\Documents and Settings\Administrator\桌面\Server\上传文件\"; ) { { View Code
{ ServiceUtil.Request(; } ; } }
DialogResult.OK) { { [block]; fileName; Path.GetFileName(fs.Name); ; ) { fs.Read(bArr,bArr.Length); } { i); bArr = [len]; fs.Read(bArr,bArr.Length); } DemoService demoService = DemoService(); ); bl) { bl = demoService.UploadFile(fileName,1)">); LogUtil.LogError(); Thread.Sleep(); } Thread.Sleep(); } fs.Close(); } MessageBox.Show(); })).Start(); } (Exception ex) { MessageBox.Show(ex.Message); } } }
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。