diff --git a/.idea/.idea.BasicBlockChain/.idea/.gitignore b/.idea/.idea.BasicBlockChain/.idea/.gitignore new file mode 100644 index 0000000..e50b8a7 --- /dev/null +++ b/.idea/.idea.BasicBlockChain/.idea/.gitignore @@ -0,0 +1,13 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Rider ignored files +/modules.xml +/contentModel.xml +/projectSettingsUpdater.xml +/.idea.BasicBlockChain.iml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/.idea.BasicBlockChain/.idea/encodings.xml b/.idea/.idea.BasicBlockChain/.idea/encodings.xml new file mode 100644 index 0000000..df87cf9 --- /dev/null +++ b/.idea/.idea.BasicBlockChain/.idea/encodings.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/.idea.BasicBlockChain/.idea/indexLayout.xml b/.idea/.idea.BasicBlockChain/.idea/indexLayout.xml new file mode 100644 index 0000000..7b08163 --- /dev/null +++ b/.idea/.idea.BasicBlockChain/.idea/indexLayout.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/.idea.BasicBlockChain/.idea/vcs.xml b/.idea/.idea.BasicBlockChain/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/.idea.BasicBlockChain/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/BasicBlockChain.Core/BasicBlockChain.Core.csproj b/BasicBlockChain.Core/BasicBlockChain.Core.csproj index 4749761..4f837a8 100644 --- a/BasicBlockChain.Core/BasicBlockChain.Core.csproj +++ b/BasicBlockChain.Core/BasicBlockChain.Core.csproj @@ -33,11 +33,11 @@ + - ..\packages\VAR.Json.1.2.0.1065\lib\net461\VAR.Json.dll @@ -46,6 +46,7 @@ + diff --git a/BasicBlockChain.Core/P2PNode.cs b/BasicBlockChain.Core/P2PNode.cs new file mode 100644 index 0000000..17d19a2 --- /dev/null +++ b/BasicBlockChain.Core/P2PNode.cs @@ -0,0 +1,131 @@ +using System.Collections.Generic; +using System.Net; +using System.Net.Sockets; +using System.Threading; + +namespace BasicBlockChain.Core +{ + public class NetNode + { + private PeerAddress _nodeAddress = null; + + private List _peers = new List(); + + private Socket _listen = null; + + private Thread _thread = null; + private bool _running = false; + + public NetNode(PeerAddress nodeAddress) + { + _nodeAddress = nodeAddress; + + StartListening(); + + _running = true; + _thread = new Thread(Run); + _thread.Start(); + } + + public void AddPeer(PeerAddress peerAddress) + { + NetPeer newPeer = new NetPeer(_nodeAddress, peerAddress); + lock (_peers) + { + _peers.Add(newPeer); + } + } + + private void StartListening() + { + _listen = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + _listen.Bind(new IPEndPoint(IPAddress.Any, _nodeAddress.Port)); + _listen.Listen(1000); + } + + private void Run() + { + while (_running) + { + if (_listen.Poll(100, SelectMode.SelectRead) == false) { continue; } + + Socket newSock = _listen.Accept(); + + NetPeer newPeer = new NetPeer(_nodeAddress, null, newSock); + lock (_peers) + { + _peers.Add(newPeer); + } + } + } + } + + public class PeerAddress + { + public string Address { get; set; } + public int Port { get; set; } + } + + public class NetPeer + { + private PeerAddress _nodeAddress = null; + private PeerAddress _peerAddress = null; + + private Socket _socket = null; + + private Thread _thread = null; + private bool _running = false; + + private enum PeerStatus + { + None, + SendingId, + WaitingId, + Idle, + Ended, + }; + private PeerStatus _status = PeerStatus.None; + + public NetPeer(PeerAddress nodeAddress, PeerAddress peerAddress, Socket socket = null) + { + _nodeAddress = nodeAddress; + _peerAddress = peerAddress; + + _socket = socket; + + _status = PeerStatus.Idle; + if (_socket == null) + { + ConnectPeer(); + _status = PeerStatus.SendingId; + } + if (peerAddress == null) + { + _status = PeerStatus.WaitingId; + } + + _socket.Blocking = false; + _socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, true); + + _running = true; + _thread = new Thread(Run); + _thread.Start(); + } + + private void ConnectPeer() + { + IPAddress ipAddress = IPAddress.Parse(_peerAddress.Address); + _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + _socket.Connect(ipAddress, _peerAddress.Port); + } + + private void Run() + { + while (_running) + { + _socket.Poll(1, SelectMode.SelectRead); + // TODO + } + } + } +} diff --git a/BasicBlockChain.sln.DotSettings.user b/BasicBlockChain.sln.DotSettings.user new file mode 100644 index 0000000..43ca5bb --- /dev/null +++ b/BasicBlockChain.sln.DotSettings.user @@ -0,0 +1,4 @@ + + <SessionState ContinuousTestingMode="0" IsActive="True" Name="All tests from Solution" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"> + <Solution /> +</SessionState> \ No newline at end of file