コード例 #1
0
ファイル: LinkFactory.cs プロジェクト: PasierbKarol/CSPsharp
        /**
         * Creates a new Link, or retrieves an existing one, from a NodeAddress
         *
         * @param addr
         *            The NodeAddress of the Node to connect to
         * @return A new Link connected to the node at the given NodeAddress
         * @//throws JCSPNetworkException
         *             Thrown if anything goes wrong during the connection
         */
        public static Link getLink(NodeAddress addr)
        ////throws JCSPNetworkException
        {
            // Log start of creation
            Node.log.log(typeof(LinkFactory), "Trying to get link to " + addr.toString());

            // Create Link from address
            Link toReturn = addr.createLink();

            Console.WriteLine("Finished creating link NodeID " + toReturn.remoteID);

            // Now attempt to connect the Link. If connect fails, then the opposite node already has a connection to us.
            // This may occur during connection if the opposite end registered its Link prior to us doing so. In such
            // a circumstance, the Link should eventually appear in the LinkManager.
            if (!toReturn.connect())
            {
                // Connect failed. Get NodeID of remote Node (this will have been set during the connect operation)
                NodeID remoteID = toReturn.getRemoteNodeID();

                // Log failed connect
                Node.log.log(typeof(LinkFactory), "Failed to connect to " + remoteID.toString());
                Console.WriteLine("Failed to connect to " + remoteID.toString());
                // Set the Link to return to null
                toReturn = null;

                // Loop until the Link is connected. This is a possible weakness. Although it is believed that the
                // opposite end will eventually connect, we may have a problem if this continually loops. For information,
                // log every attempt.
                while (toReturn == null)
                {
                    try
                    {
                        // Go to sleep for a bit, and give the Link a chance to register
                        Thread.Sleep(100);

                        // Log start of attempt
                        Node.log.log(typeof(LinkFactory), "Attempting to retrieve Link to " + remoteID.toString());

                        // Retrieve Link from LinkManager
                        toReturn = LinkManager.getInstance().requestLink(remoteID);
                    }
                    catch (ThreadInterruptedException ie)
                    {
                        // Ignore. Should never really happen
                    }
                }
                // Return the Link retrieved from the LinkManager
                return(toReturn);
            }

            // Connection succeeded. Register Link with the LinkManager
            toReturn.registerLink();

            // Now start the Link
            new ProcessManager(toReturn).start();

            // Return the Link
            return(toReturn);
        }
コード例 #2
0
ファイル: TCPIPLink.cs プロジェクト: PasierbKarol/CSPsharp
        /**
         * Creates new TCPIPLink from a Socket. This is used internally by JCSP
         *
         * @param socket
         *            The socket to create the TCPIPLink with
         * @param nodeID
         *            The NodeID of the remote Node
         * @//throws JCSPNetworkException
         *             Thrown if there is a problem during the connection
         */
        internal TCPIPLink(Socket socket, NodeID nodeID)
        //throws JCSPNetworkException
        {
            try
            {
                // Set the socket property
                this.socket = socket;
                // Set TcpNoDelay
                //socket.setTcpNoDelay(!TCPIPLink.NAGLE);
                socket.NoDelay = !TCPIPLink.NAGLE;
                // Set the input and output streams for the Link
                //this.rxStream = new BinaryReader(new BufferedInputStream(socket.getInputStream(), TCPIPLink.BUFFER_SIZE));
                //this.txStream = new BinaryWriter(new BufferedOutputStream(socket.getOutputStream(), TCPIPLink.BUFFER_SIZE));


                //this.rxStream = new BinaryReader(new BufferedInputStream(this.socket.getInputStream(), TCPIPLink.BUFFER_SIZE));
                this.rxStream = new BinaryReader(new NetworkStream(this.socket));
                //this.txStream = new BinaryWriter(new BufferedOutputStream(this.socket.getOutputStream(), TCPIPLink.BUFFER_SIZE));
                this.txStream = new BinaryWriter(new NetworkStream(this.socket));


                // Set the NodeID
                this.remoteID = nodeID;
                // Set the remote address
                this.remoteAddress = (TCPIPNodeAddress)this.remoteID.getNodeAddress();
                // Set connected to true
                this.connected = true;
                // Log Link creation and Link connection
                Node.log.log(this.GetType(), "Link created to " + nodeID.toString());
                Node.log.log(this.GetType(), "Link to " + nodeID.toString() + " connected");
            }
            catch (IOException ioe)
            {
                // Something went wrong during the creation. Log and throw exception
                Node.err.log(this.GetType(), "Failed to create Link to " + nodeID.toString());
                throw new JCSPNetworkException("Failed to create TCPIPLink to: " +
                                               nodeID.getNodeAddress().getAddress());
            }
        }
コード例 #3
0
        /**
         * The run method for the TCPIPLinkServer process
         */
        public override void run()
        {
            // Log start of Link Server
            Node.log.log(this.GetType(), "TCPIP Link Server started on " + this.listeningAddress.getAddress());
            try
            {
                // Now we loop until something goes wrong
                while (true)
                {
                    // Receive incoming connection
                    Socket incoming = this.serv.Accept();

                    //IPEndPoint remoteEndPoint = (IPEndPoint) incoming.RemoteEndPoint;
                    //Debug.WriteLine("Accepted connection from {0}:{1}.", remoteEndPoint.Address, remoteEndPoint.Port);

                    // Log
                    Node.log.log(this.GetType(), "Received new incoming connection");
                    // Set TcpNoDelay
                    incoming.NoDelay = true;

                    // Now we want to receive the connecting Node's NodeID
                    NetworkStream networkStream = new NetworkStream(incoming);

                    // Receive remote NodeID and parse
                    String otherID  = new BinaryReader(networkStream).ReadString();
                    NodeID remoteID = NodeID.parse(otherID);

                    // First check we have a tcpip Node connection
                    if (remoteID.getNodeAddress() is TCPIPNodeAddress)
                    {
                        // Create an output stream from the Socket
                        BinaryWriter outStream = new BinaryWriter(networkStream);

                        // Now Log that we have received a connection
                        Node.log.log(this.GetType(), "Received connection from: " + remoteID.toString());

                        // Check if already connected
                        if (requestLink(remoteID) == null)
                        {
                            // No existing connection to incoming Node exists. Keep connection

                            // Write OK to the connecting Node
                            outStream.Write("OK");
                            outStream.Flush();

                            // Send out our NodeID
                            outStream.Write(Node.getInstance().getNodeID().toString());
                            outStream.Flush();

                            // Create Link, register, and start.
                            TCPIPLink link = new TCPIPLink(incoming, remoteID);
                            registerLink(link);
                            new ProcessManager(link).start();
                        }
                        else
                        {
                            // We already have a connection to the incoming Node

                            // Log failed connection
                            Node.log.log(this.GetType(), "Connection to " + remoteID
                                         + " already exists.  Informing remote Node.");

                            // Write EXISTS to the remote Node
                            outStream.Write("EXISTS");
                            outStream.Flush();

                            // Send out NodeID. We do this so the opposite Node can find its own connection
                            outStream.Write(Node.getInstance().getNodeID().toString());
                            outStream.Flush();

                            // Close socket
                            incoming.Close();
                        }
                    }

                    // Address is not a TCPIP address. Close socket. This will cause an exception on the opposite Node
                    else
                    {
                        incoming.Close();
                    }
                }
            }
            catch (IOException ioe)
            {
                // We can't really recover from this. This may happen if the network connection was lost.
                // Log and fail
                Node.err.log(this.GetType(), "TCPIPLinkServer failed.  " + ioe.Message);
            }
        }
コード例 #4
0
ファイル: LinkFactory.cs プロジェクト: PasierbKarol/CSPsharp
        /**
         * Creates a new Link or gets an existing one from the the given NodeID.
         *
         * @param nodeID
         *            NodeID of the Node to connect to.
         * @return A Link connected to the remote Node of given NodeID
         * @//throws JCSPNetworkException
         *             Thrown if there is a problem connecting to the Node
         * @//throws ArgumentException
         *             Thrown if an attempt is made to connect to the local Node
         */
        public static Link getLink(NodeID nodeID)
        ////throws JCSPNetworkException, ArgumentException
        {
            if (nodeID.equals(Node.getInstance().getNodeID()))
            {
                throw new ArgumentException("Attempted to connect to the local Node");
            }

            // Log start of Link creation
            Node.log.log(typeof(LinkFactory), "Trying to get link to " + nodeID.toString());

            // First check if Link to NodeID exists. Request the Link from the Link Manager
            Link toReturn = LinkManager.getInstance().requestLink(nodeID);

            if (toReturn != null)
            {
                // A Link already exists to given NodeID. Log and return existing Link
                Node.log.log(typeof(LinkFactory), "Link to " + nodeID.toString()
                             + " already exists.  Returning existing Link");
                return(toReturn);
            }

            // An existing Link does not exist within the Link Manager. Log, and then create Link via the address
            Node.log.log(typeof(LinkFactory), "Link does not exist to " + nodeID.toString() + ".  Creating new Link");
            toReturn = nodeID.getNodeAddress().createLink();

            // Now attempt to connect the Link. If connect fails, then the opposite node already has a connection to us.
            // This may occur during connection if the opposite end registered its Link prior to us doing so. In such
            // a circumstance, the Link should eventually appear in the LinkManager.
            if (!toReturn.connect())
            {
                // Connect failed. Get NodeID of remote Node (this will have been set during the connect operation)
                NodeID remoteID = toReturn.getRemoteNodeID();

                // Log failed connect
                Node.log.log(typeof(LinkFactory), "Failed to connect to " + remoteID.toString());

                // Set the Link to return to null
                toReturn = null;

                // Loop until the Link is connected. This is a possible weakness. Although it is believed that the
                // opposite end will eventually connect, we may have a problem if this continually loops. For information,
                // log every attempt.
                while (toReturn == null)
                {
                    try
                    {
                        // Go to sleep for a bit, and give the Link a chance to register
                        Thread.Sleep(100);

                        // Log start of attempt
                        Node.log.log(typeof(LinkFactory), "Attempting to retrieve Link to " + remoteID.toString());

                        // Retrieve Link from LinkManager
                        toReturn = LinkManager.getInstance().requestLink(remoteID);
                    }
                    catch (ThreadInterruptedException ie)
                    {
                        // Ignore. Should never really happen
                    }
                }
                // Return the Link retrieved from the LinkManager
                return(toReturn);
            }

            // Connection succeeded. Register Link with the LinkManager
            toReturn.registerLink();

            // Now start the Link
            ProcessManager proc = new ProcessManager(toReturn);

            proc.setPriority(toReturn.priority);
            proc.start();

            // Return the Link
            return(toReturn);
        }
コード例 #5
0
ファイル: BNS.cs プロジェクト: PasierbKarol/CSPsharp
        /**
         * The run method for the BNS process
         */
        public void run()
        {
            // Create the channel to receive incoming messages on. The index is 2.
            NetAltingChannelInput In = NetChannel.numberedNet2One(2, new BNSNetworkMessageFilter.FilterRX());

            // We now wish to alternate upon this channel and the link lost channel
            Alternative alt = new Alternative(new Guard[] { this.lostLink, In });

            // Loop forever
            while (true)
            {
                // Select next available Guard. Give priority to link failure
                switch (alt.priSelect())
                {
                // We have lost the connection to a Node
                case 0:
                    // Read in the NodeID of the lost Node
                    NodeID lostNode = (NodeID)this.lostLink.read();

                    // Log loss of connection
                    Node.log.log(this.GetType(), "Lost Link to: " + lostNode.toString());

                    // Remove the logged client
                    this.loggedClients.Remove(lostNode);

                    // Next get the ArrayList of any barriers registered by that Node
                    ArrayList registeredBars = (ArrayList)this.barrierRegister[lostNode];

                    // If this ArrayList is null, we have no registrations
                    if (registeredBars != null)
                    {
                        // There are registered barriers

                        // Remove the list from the Hashmap
                        this.barrierRegister.Remove(lostNode);

                        // Now remove all the barriers registered by the Node
                        for (IEnumerator enumerator = registeredBars.GetEnumerator(); enumerator.MoveNext();)
                        {
                            String toRemove = (String)enumerator.Current;
                            this.registeredBarriers.Remove(toRemove);
                            Node.log.log(this.GetType(), toRemove + " deregistered");
                        }
                    }
                    break;

                // We have received a new incoming message
                case 1:
                {
                    // Read in the message
                    BNSMessage message = (BNSMessage)In.read();

                    // Now behave based on the type of the message
                    switch (message.type)
                    {
                    // We have received a logon message
                    case BNSMessageProtocol.LOGON_MESSAGE:
                    {
                        // Log the logon attempt
                        Node.log.log(this.GetType(), "Logon received from: "
                                     + message.serviceLocation.getNodeID().toString());

                        // try-catch loop. We don't want the BNS to fail
                        try
                        {
                            // Check if the node is already logged on
                            NetChannelOutput Out = (NetChannelOutput)this.loggedClients[message.serviceLocation.getNodeID()];

                            // If out is null, no previous logon received
                            if (Out != null)
                            {
                                // This Node is already logged on. Send fail message
                                // Log failed attempt
                                Node.err.log(this.GetType(), message.serviceLocation.getNodeID().toString()
                                             + " already logged on.  Rejecting");

                                // Create reply channel to the Node
                                NetChannelOutput toNewRegister = NetChannel.one2net(message.serviceLocation,
                                                                                    new BNSNetworkMessageFilter.FilterTX());

                                // Create the reply message
                                BNSMessage reply = new BNSMessage();
                                reply.type    = BNSMessageProtocol.LOGON_REPLY_MESSAGE;
                                reply.success = false;

                                // Asynchronously write to Node. We don't want the BNS to block
                                toNewRegister.asyncWrite(reply);
                                // Destroy the temporary channel
                                toNewRegister.destroy();
                            }
                            else
                            {
                                // Node hasn't previously registered
                                // Log registration
                                Node.log.log(this.GetType(), message.serviceLocation.getNodeID().toString()
                                             + " successfully logged on");

                                // Create the reply channel
                                NetChannelOutput toNewRegister = NetChannel.one2net(message.serviceLocation,
                                                                                    new BNSNetworkMessageFilter.FilterTX());

                                // Add the Node and reply channel to the logged clients map
                                this.loggedClients.Add(message.serviceLocation.getNodeID(), toNewRegister);

                                // Create a reply message
                                BNSMessage reply = new BNSMessage();
                                reply.type    = BNSMessageProtocol.LOGON_REPLY_MESSAGE;
                                reply.success = true;

                                // Write reply asynchronously to the logging on Node
                                toNewRegister.asyncWrite(reply);
                            }
                        }
                        catch (JCSPNetworkException jne)
                        {
                            // Catch any JCSPNetworkException. We don't let the BNS go down
                        }
                        break;
                    }

                    // A Node is attempting to register a Barrier
                    case BNSMessageProtocol.REGISTER_REQUEST:
                    {
                        // Log registration attempt
                        Node.log.log(this.GetType(), "Registeration for " + message.name + " received");

                        // Catch any JCSPNetworkException
                        try
                        {
                            // Get the reply channel from our logged clients map
                            NetChannelOutput Out = (NetChannelOutput)this.loggedClients[message.serviceLocation.getNodeID()];

                            // Check if the Node has logged on with us
                            if (Out == null)
                            {
                                // The Node is not logged on. Send failure message
                                Node.err.log(this.GetType(), "Registration failed. "
                                             + message.serviceLocation.getNodeID()
                                             + " not logged on");

                                // Create the channel to reply to
                                Out = NetChannel.one2net(message.serviceLocation,
                                                         new BNSNetworkMessageFilter.FilterTX());

                                // Create the reply message
                                BNSMessage reply = new BNSMessage();
                                reply.type    = BNSMessageProtocol.REGISTER_REPLY;
                                reply.success = false;

                                // Write message asynchronously to the Node
                                Out.asyncWrite(reply);

                                // Destroy the temporary channel
                                Out.destroy();
                            }

                            // The Node is registered. Now check if the name is
                            else if (this.registeredBarriers.ContainsKey(message.name))
                            {
                                // The name is already registered. Inform the register
                                // Log the failed registration
                                Node.err.log(this.GetType(), "Registration failed. " + message.name
                                             + " already registered");

                                // Create reply message
                                BNSMessage reply = new BNSMessage();
                                reply.type    = BNSMessageProtocol.RESOLVE_REPLY;
                                reply.success = false;

                                // Write the reply asynchronously. Do not block the BNS
                                Out.asyncWrite(reply);
                            }
                            else
                            {
                                BNSMessage reply;
                                // The name is not registered
                                // Log successful registration
                                Node.log.log(this.GetType(), "Registration of " + message.name + " succeeded.");

                                // First check if any client end is waiting for this name
                                ArrayList pending = (ArrayList)this.waitingResolves[message.name];

                                if (pending != null)
                                {
                                    // We have waiting resolves. Complete
                                    for (IEnumerator enumerator = pending.GetEnumerator(); enumerator.MoveNext();)
                                    {
                                        NetChannelOutput toPending = null;

                                        // We now catch internally any JCSPNetworkException
                                        try
                                        {
                                            // Get the next waiting message
                                            BNSMessage msg = (BNSMessage)enumerator.Current;

                                            // Log resolve completion
                                            Node.log.log(this.GetType(), "Queued resolve of " + message.name
                                                         + " by "
                                                         + msg.serviceLocation.getNodeID()
                                                         + " completed");

                                            // Create channel to the resolver
                                            toPending = NetChannel.one2net(msg.serviceLocation,
                                                                           new BNSNetworkMessageFilter.FilterTX());

                                            // Create the reply message
                                            reply          = new BNSMessage();
                                            reply.type     = BNSMessageProtocol.RESOLVE_REPLY;
                                            reply.location = message.location;
                                            reply.success  = true;

                                            // Write the reply asynchronously to the waiting resolver
                                            toPending.asyncWrite(reply);
                                        }
                                        catch (JCSPNetworkException jne)
                                        {
                                            // Something went wrong as we tried to send the resolution complete
                                            // message
                                            // Do nothing
                                        }
                                        finally
                                        {
                                            // Check if we need to destroy the temporary channel
                                            if (toPending != null)
                                            {
                                                toPending.destroy();
                                            }
                                        }
                                    }

                                    // Remove the name from the pending resolves
                                    this.waitingResolves.Remove(message.name);
                                }

                                // We have completed any pending resolves. Now register the barrier
                                this.registeredBarriers.Add(message.name, message.location);

                                // Now add the registered barrier to the barriers registered by this Node
                                ArrayList registered = (ArrayList)this.barrierRegister[message.serviceLocation.getNodeID()];

                                // If the ArrayList is null, we have no previous registrations
                                if (registered == null)
                                {
                                    // Create a new ArrayList to store the registered names
                                    registered = new ArrayList();
                                    // Add it to the barrier register
                                    this.barrierRegister.Add(message.location.getNodeID(), registered);
                                }

                                // Add the name to the ArrayList
                                registered.Add(message.name);

                                // Log the successful registration
                                Node.log.log(this.GetType(), message.name + " registered to " + message.location);

                                // Create the reply message
                                reply         = new BNSMessage();
                                reply.type    = BNSMessageProtocol.REGISTER_REPLY;
                                reply.success = true;

                                // Write the reply asynchronously to the Node
                                Out.asyncWrite(reply);
                            }
                        }
                        catch (JCSPNetworkException jne)
                        {
                            // Do nothing. Do not let the BNS break
                        }
                        break;
                    }

                    // We have received a resolve request
                    case BNSMessageProtocol.RESOLVE_REQUEST:
                    {
                        // Log resolve request
                        Node.log.log(this.GetType(), "Resolve request for " + message.name + " received");

                        // Catch any JCSPNetworkException
                        try
                        {
                            // Check if the resolving Node is logged on
                            NetChannelOutput Out = (NetChannelOutput)this.loggedClients[message.serviceLocation.getNodeID()];

                            // If the channel is null, then the Node has yet to log on with us
                            if (Out == null)
                            {
                                // Node is not logged on
                                // Log failed resolution
                                Node.err.log(this.GetType(), "Resolve failed. "
                                             + message.serviceLocation.getNodeID()
                                             + " not logged on");

                                // Create connection to the receiver
                                Out = NetChannel.one2net(message.serviceLocation,
                                                         new BNSNetworkMessageFilter.FilterTX());

                                // Create the reply message
                                BNSMessage reply = new BNSMessage();
                                reply.type    = BNSMessageProtocol.RESOLVE_REPLY;
                                reply.success = false;

                                // Write message asynchronously to the Node
                                Out.asyncWrite(reply);

                                // Destroy the temporary channel
                                Out.destroy();
                            }
                            else
                            {
                                // Node is logged on. Now check if the name is already registered
                                NetBarrierLocation loc = (NetBarrierLocation)this.registeredBarriers[message.name];

                                // If the location is null, then the name has not yet been registered
                                if (loc == null)
                                {
                                    // The name is not registered. We need to queue the resolve until it is
                                    // Log the queueing of the resolve
                                    Node.log.log(this.GetType(), message.name
                                                 + " not registered. Queueing resolve by "
                                                 + message.serviceLocation.getNodeID().toString());

                                    // Check if any other resolvers are waiting for the channel
                                    ArrayList pending = (ArrayList)this.waitingResolves[message.name];

                                    // If the ArrayList is null, no one else is waiting
                                    if (pending == null)
                                    {
                                        // No one else is waiting. Create a new list and add it to the waiting
                                        // resolves
                                        pending = new ArrayList();
                                        this.waitingResolves.Add(message.name, pending);
                                    }

                                    // Add this resolve message to the list of waiting resolvers
                                    pending.Add(message);
                                }
                                else
                                {
                                    // The location is not null. Send it to the resolver
                                    Node.log.log(this.GetType(), "Resolve request completed. " + message.name
                                                 + " location being sent to "
                                                 + message.serviceLocation.getNodeID());

                                    // Create channel to the resolver
                                    NetChannelOutput toPending = NetChannel.one2net(message.serviceLocation,
                                                                                    new BNSNetworkMessageFilter.FilterTX());

                                    // Create the reply message
                                    BNSMessage reply = new BNSMessage();
                                    reply.type     = BNSMessageProtocol.RESOLVE_REPLY;
                                    reply.location = loc;
                                    reply.success  = true;

                                    // Write the reply to the resolver asynchronously
                                    toPending.asyncWrite(reply);

                                    // Destroy the temporary channel
                                    toPending.destroy();
                                }
                            }
                        }
                        catch (JCSPNetworkException jne)
                        {
                            // Something went wrong during the resolution. Ignore
                        }
                        break;
                    }
                    }
                    break;
                }
                }
            }
        }