public static void sendResourceInfo(IPEndPoint destination, RingInfo ringInfo, Resource[] resources)
        {
            byte[] message = new byte[Constants.WRITEBUFFSIZE];
            MemoryStream stream;

            try
            {
                User user = User.getInstance();
                BinaryFormatter serializer = new BinaryFormatter();
                stream = new MemoryStream(message);

                NetLib.insertEntropyHeader(serializer, stream);

                serializer.Serialize(stream, Constants.MessageTypes.MSG_QUERYHIT);
                serializer.Serialize(stream, ringInfo.ring.ringID);
                serializer.Serialize(stream, ringInfo.token);
                serializer.Serialize(stream, new Peer(user.node, user.publicUserInfo, ringInfo.IE));
                serializer.Serialize(stream, resources.Length);

                foreach (Resource resource in resources)
                {
                    serializer.Serialize(stream, resource.header);
                }

                NetLib.communicateAsync(destination, message, false);
            }
            catch (Exception e)
            {
                int x = 2;
            }
        }
 public QueryCache(string[] __query, IPEndPoint __sender, uint __ringID, DateTime __timestamp)
 {
     query = __query;
     sender = __sender;
     ringID = __ringID;
     timestamp = __timestamp;
 }
        /// <summary>
        /// Connects to the end point (node) and sends message to it. If waitForReply is set
        /// it will wait for a reply from the node and return the reply
        /// </summary>
        /// <param name="node">The end point (node) in the network to communicate with</param>
        /// <param name="message">Message to send to node</param>
        /// <param name="waitForReply">Whether a reply is expected</param>
        /// <returns></returns>
        public static byte[] communicate(IPEndPoint node, byte[] message, bool waitForReply)
        {
            NetworkStream nodeStream = null;
            BinaryReader reader = null;
            BinaryWriter writer = null;
            byte[] reply = new byte[Constants.READBUFFSIZE];
            int bytesRead = 0;

            try
            {
                nodeStream = OpenCommunicationChannel(node);

                reader = new BinaryReader(nodeStream);
                writer = new BinaryWriter(nodeStream);

                writer.Write(message);
                writer.Flush();

                if(waitForReply)
                    bytesRead = reader.Read(reply, 0, reply.Length);

                reader.Close();
                writer.Close();
            }
            catch (Exception e)
            {
                return null;
            }
            finally
            {
                nodeStream.Close();
            }

            if(bytesRead == 0)
                return null;

            return reply;
        }
        /// <summary>
        /// Connects to the end point (node) and sends message to it. If waitForReply is set
        /// it will wait for a reply from the node and return the reply. It uses Asynchronous UDP
        /// protocol
        /// </summary>
        /// <param name="node">The end point (node) in the network to communicate with</param>
        /// <param name="message">Message to send to node</param>
        /// <param name="waitForReply">Whether a reply is expected</param>
        /// <returns></returns>
        public static byte[] communicateAsync(IPEndPoint node, byte[] message, bool waitForReply)
        {
            Connection nodeConnection = null;
            UdpClient udpClient = null;
            byte[] reply = null;

            try
            {
                //connect to node
                nodeConnection = new Connection(node);
                udpClient = nodeConnection.connect_async();
                if(udpClient == null)
                {
                    nodeConnection.disconnect_async();
                    return null;
                }

                udpClient.Send(message, message.Length);
                System.Net.IPEndPoint senderEndPoint = new System.Net.IPEndPoint(0,0);

                if(waitForReply)
                    reply = udpClient.Receive(ref senderEndPoint);
            }
            catch (Exception e)
            {
                return null;
            }
            finally
            {
                nodeConnection.disconnect_async();
            }

            if(reply != null && reply.Length == 0)
                return null;

            return reply;
        }
        public static NetworkStream OpenCommunicationChannel(IPEndPoint node)
        {
            Connection nodeConnection = null;
            NetworkStream nodeStream = null;

            try
            {
                //connect to node
                nodeConnection = new Connection(node);
                nodeStream = nodeConnection.connect_sync();
                if(nodeStream == null)
                {
                    nodeConnection.disconnect_sync();
                    return null;
                }
            }
            catch (Exception e)
            {
                int x = 2;

                if(nodeConnection != null)
                    nodeConnection.disconnect_sync();
            }

            return nodeStream;
        }
        /*public static void listenAndCommunicate(IPEndPoint localEndPoint, handleConnection handler)
        {
            TcpClient client;
            byte[] buffer = new byte[Constants.READBUFFSIZE];
            MemoryStream stream = new MemoryStream(buffer);

            try
            {
                TcpListener listener = new TcpListener(localEndPoint);
                listener.Start();

                //ConnectionState state = new ConnectionState(handler, socket, buffer);
                while (true)
                {
                    TcpConnectionDone.Reset();
                    client = listener.AcceptTcpClient();
                    if (client.GetStream().CanRead)
                    {
                        client.GetStream().Read(buffer, 0, buffer.Length);

                        handler(new BinaryReader(stream), new BinaryWriter(stream));
                        //client.GetStream().BeginRead(state.buffer, 0, state.buffer.Length, SocketFlags.None,
                        //	new AsyncCallback(ReceiveCallback), state);

                        //socket.BeginReceive(state.buffer, 0, state.buffer.Length, SocketFlags.None,
                        //	new AsyncCallback(ReceiveCallback), state);
                        TcpConnectionDone.WaitOne();
                    }
                }
            }
            catch (Exception e)
            {
                int x = 2;
            }
        }*/
        public static void listenAndCommunicateAsync(IPEndPoint localEndPoint, handleConnection handler)
        {
            Socket socket;
            byte[] buffer = new byte[Constants.READBUFFSIZE];

            try
            {
                socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
                socket.Bind(localEndPoint.GetEndPoint());
                ConnectionState state = new ConnectionState(handler, socket, buffer);
                while (true)
                {
                    UdpConnectionDone.Reset();
                    socket.BeginReceive(state.buffer, 0, state.buffer.Length, SocketFlags.None,
                        new AsyncCallback(ReceiveCallback), state);
                    UdpConnectionDone.WaitOne();
                }
            }
            catch (Exception e)
            {
                int x = 2;
            }
        }
        public static void listenAndCommunicate(IPEndPoint localEndPoint, handleConnection handler)
        {
            TcpListener TCPListener = null;
            Socket newConnection = null;
            NetworkStream clientStream = null;
            BinaryReader reader = null;
            BinaryWriter writer = null;
            byte[] buffer = new byte[Constants.READBUFFSIZE];

            try
            {
                TCPListener = new TcpListener(localEndPoint.GetEndPoint());
                TCPListener.Start();

                while(true)
                {
                    newConnection = TCPListener.AcceptSocket();
                    //newConnection.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.KeepAlive,
                    //	1);

                    if(!newConnection.Connected)
                    {
                        newConnection.Close();
                        continue;
                    }

                    //Get streams to the client so we can read and write to it.
                    clientStream = new NetworkStream(newConnection);
                    //If we can't read and write to the client abort connection
                    if(!clientStream.CanRead || !clientStream.CanWrite)
                    {
                        clientStream.Close();
                        newConnection.Close();
                        continue;
                    }
                    reader = new BinaryReader(clientStream);
                    writer = new BinaryWriter(clientStream);

                    //newConnection.Receive(buffer, 0, buffer.Length, SocketFlags.None);
                     reader.Read(buffer, 0, buffer.Length);

                    reader = new BinaryReader(new MemoryStream(buffer));

                    //process the message
                    handler(reader, writer);

                    reader.Close();
                    writer.Close();
                    clientStream.Close();
                    newConnection.Close();
                }
            }
            catch (Exception e)
            {
                int x = 2;
            }
            finally
            {
                if(clientStream != null)
                    clientStream.Close();
                if(newConnection != null)
                    newConnection.Close();
            }
        }
 public Ring(uint __ringID, string __ringName, IPEndPoint[] __lords)
 {
     ringID = __ringID;
     ringName = __ringName;
     lords = __lords;
 }
 public Connection(IPEndPoint __node)
 {
     node = __node;
 }
 public LordInfo(uint __ringID, IPEndPoint[] __lords)
 {
     ringID = __ringID;
     lords = __lords;
 }
 public LordInfo(uint __ringID, IPEndPoint __lord)
 {
     ringID = __ringID;
     lords = new IPEndPoint[1];
     lords[0] = __lord;
 }
 public Node(IPEndPoint syncCommPoint, IPEndPoint asyncCommPoint, Constants.LineSpeedType __lineSpeed)
 {
     syncCommunicationPoint = syncCommPoint;
     asyncCommunicationPoint = asyncCommPoint;
     lineSpeed = __lineSpeed;
 }
        private void getRingNeighbors(IPEndPoint lord, Ring ring)
        {
            byte[] message = new byte[Constants.WRITEBUFFSIZE];
            byte[] reply = new byte[Constants.READBUFFSIZE];
            MemoryStream stream;

            try
            {
                User user = User.getInstance();
                BinaryFormatter serializer = new BinaryFormatter();
                stream = new MemoryStream(message);

                NetLib.insertEntropyHeader(serializer, stream);

                serializer.Serialize(stream, Constants.MessageTypes.MSG_RINGLOGIN);
                serializer.Serialize(stream, ring.ringID);
                RingInfo ringInfo = user.findRingInfo(ring.ringID);
                serializer.Serialize(stream, ringInfo.userName);
                serializer.Serialize(stream, SecurityLib.encrypt(ringInfo.password));
                serializer.Serialize(stream, user.node.syncCommunicationPoint);
                serializer.Serialize(stream, ringInfo.IE);

                reply = NetLib.communicate(lord, message, true);

                BinaryFormatter deserializer = new BinaryFormatter();
                stream = new MemoryStream(reply);
                NetLib.bypassEntropyHeader(deserializer, stream);
                Constants.MessageTypes replyMsg = (Constants.MessageTypes)deserializer.Deserialize(stream);
                Constants.QueryHandlerType howToHandleQuery;
                switch(replyMsg)
                {
                    case Constants.MessageTypes.MSG_RINGNEIGHBORS:
                        ringInfo.token = (ulong)serializer.Deserialize(stream);
                        howToHandleQuery = (Constants.QueryHandlerType)serializer.Deserialize(stream);
                        ringInfo.queryServer = (IPEndPoint)serializer.Deserialize(stream);
                        switch(howToHandleQuery)
                        {
                            case Constants.QueryHandlerType.SERVER_FORM_QUERY:
                                ringInfo.searchRing =
                                    new RingInfo.ringSearcher(ringInfo.searchRingServerFormQuery);
                                break;
                            case Constants.QueryHandlerType.SERVER_RESOLVE_QUERY:
                                ringInfo.searchRing =
                                    new RingInfo.ringSearcher(ringInfo.searchRingServerResolveQuery);
                                break;
                            case Constants.QueryHandlerType.DISTRIBUTED_PEER_QUERY:
                                ringInfo.searchRing =
                                    new RingInfo.ringSearcher(ringInfo.searchRingDistributedP2PEntropy);
                                break;
                        }

                        Peer[] neighbors = (Peer[])deserializer.Deserialize(stream);
                        foreach (Peer neighbor in neighbors)
                            ringInfo.neighbors.Add(new Neighbor(neighbor, new NeighborProxy()));
                        break;
                    default:
                        ringInfo.neighbors = null;
                        break;
                }
            }
            catch (Exception e)
            {
                int x = 2;
            }
        }