Exemple #1
0
        private async void HandleClient(Socket clientSocket)
        {
            try {
                clientSocket.NoDelay = true;

                using var stream = new NetworkStream(clientSocket, ownsSocket: true)
                      {
                          ReadTimeout  = 3000,
                          WriteTimeout = 3000,
                      };

                var messageBuffer = new byte[64];
                random.Value !.NextBytes(messageBuffer.AsSpan(0, 32));
                await stream.WriteAsync(messageBuffer.AsMemory(0, 32), cancellationTokenSource.Token);

                // 32字节另一半消息
                // 64字节公钥
                // 64字节签名
                var buffer = new byte[160];
                await stream.FillAsync(buffer, cancellationTokenSource.Token);

                buffer.AsSpan(0, 32).CopyTo(messageBuffer.AsSpan(32));
                byte[] messageHash = Sha256.ComputeHashToArray(messageBuffer);
                if (messageHash[0] != 0)
                {
                    return;                      // 工作量证明,hash前8位必须是0
                }
                var(pubkey, sign) = ReadPublicKeySignature(buffer.AsSpan(32));
                var superAddress = pubkey.ToAddress();
                if (!system.IsProducer(superAddress))
                {
                    return;
                }
                if (!Secp256k1.Secp256k1.Verify(pubkey, messageHash, sign))
                {
                    return;
                }

                // 认证通过,开始处理请求
                stream.ReadTimeout = -1;
                var clientNode = new SuperNode(pubkey, (IPEndPoint)clientSocket.RemoteEndPoint, isReadOnly: true)
                {
                    ClientSocket = clientSocket
                };
                ClientConnected?.Invoke(this, new SuperNodeEventArgs(clientNode, Array.Empty <byte>()));

                try {
                    var arrayPool = ArrayPool <byte> .Create(65536, 1);

                    while (cancellationTokenSource.IsCancellationRequested is false && clientSocket.Connected)
                    {
                        var packetLength = await stream.ReadStructAsync <int>(cancellationTokenSource.Token);

                        if (BitConverter.IsLittleEndian is false)
                        {
                            packetLength = BinaryPrimitives.ReverseEndianness(packetLength);
                        }
                        if (packetLength is 0 || packetLength > 10485760)
                        {
                            return;
                        }

                        byte[] packetBuffer = arrayPool.Rent(packetLength);
                        await stream.FillAsync(packetBuffer.AsMemory(0, packetLength), cancellationTokenSource.Token);

                        // TODO: 处理请求
                        DataArrived?.Invoke(this, new SuperNodeEventArgs(clientNode, packetBuffer.AsMemory(0, packetLength)));

                        arrayPool.Return(packetBuffer);
                    }
                } catch {
                }
                Closed?.Invoke(this, new SuperNodeEventArgs(clientNode, Array.Empty <byte>()));
            } catch {
            }