/// <summary> /// this method is blocked for running services /// </summary> /// <param name="port">listening port</param> public void Run(int port) { Socket srv = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); srv.ExclusiveAddressUse = false; srv.Bind(new IPEndPoint(IPAddress.Any, port)); srv.Listen(int.MaxValue); srvs.Add(srv); while (true) { Socket socket = srv.Accept(); new Thread(() => { try { byte[] buf = new byte[1024]; while (true) { RecvBuf recv = new RecvBuf(); while (true) { if (recv.Size.HasValue && recv.Size.Value == recv.Len) { break; } int read = socket.Receive(buf); if (read > 0) { recv.Append(buf, read); } else { socket.Shutdown(SocketShutdown.Both); socket.Dispose(); return; } } byte[] rst = new SendData(srvFun.Invoke(recv.ByteQue)).ToArray(); int write = 0; while (true) { write += socket.Send(rst, write, rst.Length - write, SocketFlags.None); if (write >= rst.Length) { break; } } } } catch { socket.Shutdown(SocketShutdown.Both); socket.Dispose(); } }).Start(); } }
/// <summary> /// call the server method /// </summary> /// <typeparam name="T">any type can be used here when the server is void</typeparam> /// <param name="fun">data generated by Fun.fun</param> /// <returns>the data returned by the server is null when there is no return value</returns> public T Invoke <T>(ByteQue fun) { byte[] data = new SendData(fun).ToArray(); int write = 0; while (true) { write += socket.Send(data, write, data.Length - write, SocketFlags.None); if (write >= data.Length) { break; } } RecvBuf recv = new RecvBuf(); byte[] buf = new byte[1024]; while (true) { if (recv.Size.HasValue && recv.Size == recv.Len) { break; } int read = socket.Receive(buf); if (read > 0) { recv.Append(buf, read); } else { Dispose(); throw new Exception("remote connection has been disconnected"); } } ByteQue ret = recv.ByteQue; String msg = ret.Pop <string>(); if (msg != null) { throw new Exception(msg); } if (ret.Len > 0) { return(ret.Pop <T>()); } return(default(T)); }