using System; using System.Net; using System.Collections.Generic; using System.Threading; using System.Net.Sockets; using sharp.cryptonote; using Newtonsoft.Json.Linq; namespace SharpMining { public delegate void StratumConnectionAccepted(StratumListener listener, StratumConnection stratumConnection); public class StratumListener : TcpListener { bool shouldExit; List connections; Thread thread; Dictionary associatedPools; public event StratumConnectionAccepted OnConnectionAccepted; public StratumListener(IPEndPoint endpoint) :base(endpoint) { this.initialize(); } public StratumListener(IPAddress bind,int port) :base(bind,port) { this.initialize(); } public StratumListener(string bind, int port) :base(IPAddress.Parse(bind),port) { this.initialize(); } public StratumListener(JToken stratumConfig) :base(IPAddress.Parse(stratumConfig["bind"].ToString()),stratumConfig["port"].ToObject()) { this.initialize(); } private void initialize(){ this.associatedPools = new Dictionary(); this.connections = new List(); } public new void Start(){ if (thread == null){ thread = new Thread(() => run()); thread.Start(); } } public new void Stop(){ Monitor.Enter(this); shouldExit = true; Monitor.Wait(this); Monitor.Exit(this); } protected void ConnectionAccepted(StratumConnection connection){ if (OnConnectionAccepted != null){ OnConnectionAccepted(this,connection); } } private void run(){ base.Start(5); while (!ShouldExit){ StratumConnection connection = AcceptStratumConnection(); connection.OnConnectionClosed += (sender) => { removeConnection(connection); }; this.connections.Add(connection); ConnectionAccepted(connection); } base.Stop(); Monitor.Enter(this); this.thread = null; foreach (StratumConnection c in this.connections){ c.Close(); } Monitor.PulseAll(this); Monitor.Exit(this); } public StratumConnection AcceptStratumConnection(){ return new StratumConnection(this,this.AcceptSocket()); } private void removeConnection(StratumConnection connection){ this.connections.Remove(connection); Console.WriteLine("StratumConnection lost: {0}",connection); } private bool ShouldExit { get { Monitor.Enter(this); bool se = this.shouldExit; Monitor.Exit(this); return se; } } public StratumConnection[] Connections { get { return this.connections.ToArray(); } } public MiningPool[] AssociatedPools { get { MiningPool[] pools = new MiningPool[this.associatedPools.Count]; this.associatedPools.Values.CopyTo(pools,0); return pools; } } public MiningPool getAssociatedPool(CryptoNoteCoin coin){ if (!this.associatedPools.ContainsKey(coin)){ return null; } return this.associatedPools[coin]; } public void associatePool(MiningPool pool){ this.associatedPools[pool.Coin] = pool; } } }