예제 #1
0
        private void clientListenThread(object obj)
        {
            TcpClient     client      = (TcpClient)obj;
            StringBuilder sb          = new StringBuilder();
            int           bytesRead   = 0;
            int           bytesToRead = 0;

            while (true)
            {
                try
                {
                    byte[] data       = new byte[1024 * 8];
                    int    dataLenght = client.Client.Receive(data);
                    //Console.WriteLine("total size: " + dataLenght);
                    if (dataLenght == 0)
                    {
                        Console.WriteLine("Disconnected");
                        clients.Remove(client);
                        break;
                    }

                    int offset = 0;
                    //Split data
                    while (offset < dataLenght)
                    {
                        if (bytesRead >= bytesToRead)
                        {
                            sb.Clear();
                            bytesRead = 0;

                            //There is a super small chance that the size bytes does not come at the same time, that has not been accounted for
                            byte[] byteSize = { data[offset + 0], data[offset + 1], data[offset + 2], data[offset + 3] };
                            int    size     = BitConverter.ToInt32(byteSize, 0);
                            bytesToRead = size;
                            //Console.WriteLine("data size: " + size);
                            offset += 4;

                            if (offset >= dataLenght)
                            {
                                break;
                            }
                        }

                        for (int i = offset; i < offset + bytesToRead; i++)
                        {
                            if (i >= dataLenght)
                            {
                                break;
                            }
                            sb.Append(Convert.ToChar(data[i]));
                            bytesRead++;
                        }

                        if (bytesRead < bytesToRead)
                        {
                            break;
                        }

                        offset += bytesRead;

                        Console.WriteLine("From " + ((IPEndPoint)client.Client.RemoteEndPoint).Address.ToString() + ": " + sb.ToString());

                        //Must be of json data or it will crash
                        JMessage message = JMessage.Deserialize(sb.ToString());

                        if (message.Type == typeof(Command))
                        {
                            Command c = message.Value.ToObject <Command>();
                            if (c.command == "getBlockHeight")
                            {
                                sendDataTo(client, new BlockHeight(blockchain.Count));
                            }
                            else if (c.command == "sync")
                            {
                                /*foreach(TinyBlock tb in blockchain)
                                 * {
                                 *  sendDataTo(client, tb);
                                 * }*/
                                sendSyncList(client);
                            }
                        }
                        else if (message.Type == typeof(TinyBlock))
                        {
                            hashMre.Reset();
                            TinyBlock tb = message.Value.ToObject <TinyBlock>();
                            if (tb.verifyBlock(blockchain.Last()))
                            {
                                blockchain.Add(tb);
                            }
                            hashMre.Set();
                        }
                        else if (message.Type == typeof(SyncList))
                        {
                            SyncList syncList = message.Value.ToObject <SyncList>();
                            startSyncing(syncList);
                        }
                        else if (message.Type == typeof(BlockHeight))
                        {
                            BlockHeight c = message.Value.ToObject <BlockHeight>();
                            syncCount++;

                            if (c.value > blockchain.Count && syncBlockSize < c.value)
                            {
                                syncBlockSize = c.value;
                                syncClient    = client;
                            }
                            if (syncCount == clients.Count && syncClient != null)
                            {
                                syncCount = 0;
                                sendDataTo(syncClient, new Command("sync"));
                                //blockchain.Clear();
                            }
                        }
                    }
                }
                catch (SocketException e)
                {
                    Console.WriteLine(e.Message);
                    clients.Remove(client);
                    break;
                }
            }
        }
예제 #2
0
 public static string Serialize(JMessage message)
 {
     return(JToken.FromObject(message).ToString());
 }