Exemplo n.º 1
0
        /**
         * Connects the Link to the remote Node. Exchanges the NodeIDs
         *
         * @return True if the Link successfully connected to the remote Link
         * @//throws JCSPNetworkException
         *             Thrown if something goes wrong during the connection
         */
        public override Boolean connect()
        //throws JCSPNetworkException
        {
            // First check if we are connected.
            if (this.connected)
            {
                return(true);
            }

            // Flag to determine if we are connected at the end of the process.
            Boolean toReturn = false;

            try
            {
                // Write the string representation of our NodeID to the remote Node
                this.txStream.Write(Node.getInstance().getNodeID().toString());
                this.txStream.Flush();

                // Read in the response from the opposite Node
                String response = this.rxStream.ReadString();

                // Either the connection has been accepted (no connection to this Node exists on the opposite Node) or
                // it has not. The opposite Node sends OK in the first instance.
                if (response.Equals("OK", StringComparison.OrdinalIgnoreCase))
                {
                    // The connection is to be kept. Log, and set toReturn to true
                    Node.log.log(this.GetType(), "Link to " + this.remoteAddress.toString() + " connected");
                    toReturn = true;
                }

                // Read in Remote NodeID as string
                NodeID otherID = NodeID.parse(this.rxStream.ReadString());

                // First check we have a tcpip Node connection. This should always be the case
                if (otherID.getNodeAddress() is TCPIPNodeAddress)
                {
                    // Set address and NodeID. If we are not connected then this NodeID can be used to
                    // get the actual Link from the LinkManager
                    this.remoteAddress = (TCPIPNodeAddress)otherID.getNodeAddress();
                    this.remoteID      = otherID;

                    // Set connected to toReturn
                    this.connected = toReturn;
                    return(toReturn);
                }

                // We do not have a tcpip? Should never really happen however. Log and throw Exception
                Node.err.log(this.GetType(), "Tried to connect a TCPIPLink to a non TCPIP connection");
                throw new JCSPNetworkException("Tried to connect a TCPIPLink to a non TCPIP connection");
            }
            catch (IOException ioe)
            {
                // Something went wrong during the connection process. Log and throw exception.
                Node.err.log(this.GetType(), "Failed to connect TCPIPLink to: " + this.remoteAddress.getAddress());
                throw new JCSPNetworkException("Failed to connect TCPIPLink to: " + this.remoteAddress.getAddress());
            }
        }
Exemplo n.º 2
0
        /**
         * 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());
            }
        }
Exemplo n.º 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);
            }
        }
Exemplo n.º 4
0
        /**
         * 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);
        }