public void Start <T>(StoreAction <T> store, ActionWithData <T> action, StopCondition <T> closeConnectionCondition) where T : class { onStart(); try { serverSocket.Bind(ipEndPoint); serverSocket.Listen(config.MaxConnections); ThreadParams <T> param = new ThreadParams <T>(store, action, closeConnectionCondition); Thread connectionListener = new Thread(Listen <T>); connectionListener.Start(param); string cmd; while (true) { cmd = Console.ReadLine(); if (cmd.Equals(config.ServerStopCommand)) { break; } } connectionListener.Abort("Stopping server."); connectionListener.Join(); serverSocket.Shutdown(SocketShutdown.Both); serverSocket.Close(); } catch (Exception e) { Console.WriteLine(e.Message); } }
/// <summary> /// This method returns an Action that can be executed to run the /// current set of actions. The reason for this function is that if /// you are using ActionSet in a context where you might Clear() it, /// ie to do single-shot actions, if you call Run() and then Clear(), /// then if any registered Actions are registering other Actions, they /// would be immediately discarded. This prevents useful idioms like /// chaining a sequence of Actions. /// So usage would be: /// Action saveF = set.GetRunnable(); set.Clear(); saveF(); /// </summary> public Action GetRunnable() { Action[] copyActions = Actions.ToArray(); ActionWithData[] copyDataActions = DataActions.ToArray(); Action[] copyNamedActions = new Action[NamedActions.Count]; NamedActions.Values.CopyTo(copyNamedActions, 0); ActionWithData[] copyNamedDataActions = new ActionWithData[NamedDataActions.Count]; NamedDataActions.Values.CopyTo(copyNamedDataActions, 0); Action runnable = () => { for (int i = 0; i < copyActions.Length; ++i) { copyActions[i](); } for (int i = 0; i < copyDataActions.Length; ++i) { copyDataActions[i].F(copyDataActions[i].D); } for (int i = 0; i < copyNamedActions.Length; ++i) { copyNamedActions[i](); } for (int i = 0; i < copyNamedDataActions.Length; ++i) { copyNamedDataActions[i].F(copyNamedDataActions[i].D); } }; return(runnable); }
public ThreadParams(StoreAction <T> store, ActionWithData <T> action, StopCondition <T> closeConnectionCondition) { this.store = store; this.action = action; this.closeConnectionCondition = closeConnectionCondition; }
public void Connect <T>(IPAddress address, int port, AccessToData <T> accessToData, GetBytes <T> bytesGetter, StoreAction <T> store, ActionWithData <T> action, StopCondition <T> closeConnectionCondition) where T : class { IPEndPoint ipEndPoint = new IPEndPoint(address, port); Socket sender = new Socket(address.AddressFamily, SocketType.Stream, ProtocolType.Tcp); sender.Connect(ipEndPoint); byte[] buffer = new byte[config.BufferSize]; while (true) { T data = accessToData(); if (closeConnectionCondition(data)) { onCloseConnection(); sender.Shutdown(SocketShutdown.Both); sender.Close(); return; } byte[] dataBytes = bytesGetter(data); int bytesRest = dataBytes.Length; while (bytesRest > 0) { int bytesSent = sender.Send(dataBytes); dataBytes = dataBytes.Skip(bytesSent).ToArray(); bytesRest -= bytesSent; } while (sender.Available > 0) { int byteRecived = sender.Receive(buffer); data = store(buffer, byteRecived, data); } data = action(data); } }