protected void Transmit(Frame token) { // Send until THT reached // first send the token ack Frame sendFrame; Frame recieveFrame; byte[] bFrame; String[] splitInput; int dataSize; this.THT = 1040; Frame newToken; // send ack for token sendFrame = new Frame(0, token.SA, this.nodeNum, null); sendFrame.FS = 2; bFrame = sendFrame.ToBinary(); sendStream.Write(bFrame, 0, bFrame.Length); // read from file, and build frame from it while (true) { // tokenize the input line splitInput = this.inputFile[index].Split(new char[] { ',' }); dataSize = Convert.ToByte(splitInput[1]); // the size of data is always in the second array element if (dataSize > 254) { Console.WriteLine("LOL BAD STUFF"); } if (this.THT < dataSize) { // not enough THT to send the frame, send a token newToken = new Token(0, 0, this.nodeNum); bFrame = newToken.ToBinary(); sendStream.Write(bFrame, 0, bFrame.Length); recieveFrame = Frame.MakeFrame(Receive()); Debug.Assert(recieveFrame.DA == this.nodeNum); Debug.Assert(recieveFrame.FS == 2 || recieveFrame.FS == 3); return; } // otherwise, build and send the frame sendFrame = new Frame(0, Convert.ToByte(splitInput[0]), this.nodeNum, new System.Text.UTF8Encoding().GetBytes(splitInput[2])); bFrame = sendFrame.ToBinary(); sendStream.Write(bFrame, 0, bFrame.Length); THT -= sendFrame.size; // recieve ack while (true) { recieveFrame = Frame.MakeFrame(Receive()); Debug.Assert(recieveFrame.SA == this.nodeNum); Debug.Assert(recieveFrame.DA == sendFrame.DA); Debug.Assert(recieveFrame.FS == 2 || recieveFrame.FS == 3); // frame wasn't accepted, resend if (recieveFrame.FS == 3) { // is there enough THT to resend? if (this.THT > sendFrame.size) { // send it! sendStream.Write(bFrame, 0, bFrame.Length); THT -= sendFrame.size; continue; } else { // send the token along newToken = new Token(0, 0, this.nodeNum); bFrame = newToken.ToBinary(); sendStream.Write(bFrame, 0, bFrame.Length); recieveFrame = Frame.MakeFrame(Receive()); Debug.Assert(recieveFrame.DA == this.nodeNum); Debug.Assert(recieveFrame.FS == 2 || recieveFrame.FS == 3); return; } } else { // frame was successfully recieved, move onto the next one this.index++; if (this.index >= this.inputFile.Length) { // nothing more to send newToken = new Token(0, 0, this.nodeNum); bFrame = newToken.ToBinary(); sendStream.Write(bFrame, 0, bFrame.Length); recieveFrame = Frame.MakeFrame(Receive()); Debug.Assert(recieveFrame.DA == this.nodeNum); Debug.Assert(recieveFrame.FS == 2 || recieveFrame.FS == 3); return; } break; } } } }
protected void Transmit(Frame token) { // Send until THT reached // first send the token ack Frame sendFrame; Frame recieveFrame; byte[] bFrame; int dataSize; this.THT = 1040; Frame newToken; Queue<Frame> sendQueue; Object locker; // send ack for token sendFrame = new Frame(0, token.SA, this.nodeNum, null); sendFrame.FS = 2; bFrame = sendFrame.ToBinary(); sendStream.Write(bFrame, 0, bFrame.Length); // setup which buffer to send from if (bridgeNumber == 1) { lock (buf1Locker) { sendQueue = buffer1; locker = buf1Locker; } } else { lock (buf2Locker) { sendQueue = buffer2; locker = buf1Locker; } } // read from buffer and send it while (true) { // get the next frame to send and its size lock (locker) { sendFrame = sendQueue.Peek(); } dataSize = sendFrame.size; if (this.THT < dataSize) { // not enough THT to send the frame, send a token newToken = new Token(0, 0, this.nodeNum); bFrame = newToken.ToBinary(); sendStream.Write(bFrame, 0, bFrame.Length); recieveFrame = Frame.MakeFrame(Receive()); //Debug.Assert(recieveFrame.DA == this.nodeNum); Debug.Assert(recieveFrame.FS == 2 || recieveFrame.FS == 3); return; } // otherwise, send the frame bFrame = sendFrame.ToBinary(); sendStream.Write(bFrame, 0, bFrame.Length); THT -= sendFrame.size; // recieve ack while (true) { recieveFrame = Frame.MakeFrame(Receive()); //Debug.Assert(recieveFrame.SA == this.nodeNum); //Debug.Assert(recieveFrame.DA == sendFrame.DA); //Debug.Assert(recieveFrame.FS == 2 || recieveFrame.FS == 3); // if it needs to be setup into the routing table if (recieveFrame.AC == 4) { // if the frame recieved doesn't have the FS changed, nothing processed it if (recieveFrame.FS == 0) { lock (locker) { sendQueue.Dequeue(); if (sendQueue.Count == 0) { // nothing more to send newToken = new Token(0, 0, this.nodeNum); bFrame = newToken.ToBinary(); sendStream.Write(bFrame, 0, bFrame.Length); recieveFrame = Frame.MakeFrame(Receive()); //Debug.Assert(recieveFrame.DA == this.nodeNum); Debug.Assert(recieveFrame.FS == 2 || recieveFrame.FS == 3); return; } } break; } // otherwise, add it to the routing table else { lock (lookupTableLocker) { if (!lookupTable.Contains(sendFrame.DA)) { lookupTable.Add(sendFrame.DA, bridgeNumber); lock (logLocker) { logFile.WriteLine(DateTime.Now.ToString() + " " + sendFrame.DA + " added to the routting table"); } } } // make sure that if it needs to be resent, it doesn't get added again sendFrame.AC = 0; break; } } // frame wasn't accepted, resend else if (recieveFrame.FS == 3) { // is there enough THT to resend? if (this.THT > sendFrame.size) { lock (logLocker) { //logFile.WriteLine(DateTime.Now.ToString() + " resending frame to " + sendFrame.DA + " from " + sendFrame.SA); } // send it! sendStream.Write(bFrame, 0, bFrame.Length); THT -= sendFrame.size; continue; } else { // send the token along newToken = new Token(0, 0, this.nodeNum); bFrame = newToken.ToBinary(); sendStream.Write(bFrame, 0, bFrame.Length); recieveFrame = Frame.MakeFrame(Receive()); //Debug.Assert(recieveFrame.DA == this.nodeNum); Debug.Assert(recieveFrame.FS == 2 || recieveFrame.FS == 3); return; } } else { // frame was successfully recieved, move onto the next one lock (locker) { sendQueue.Dequeue(); if (sendQueue.Count == 0) { // nothing more to send newToken = new Token(0, 0, this.nodeNum); bFrame = newToken.ToBinary(); sendStream.Write(bFrame, 0, bFrame.Length); recieveFrame = Frame.MakeFrame(Receive()); //Debug.Assert(recieveFrame.DA == this.nodeNum); Debug.Assert(recieveFrame.FS == 2 || recieveFrame.FS == 3); return; } } break; } } } }
// monitors run, since it will only accept a token public override void Run() { // connect with neighboring nodes this.Connect(); // Accept incoming connection and wait for // right neighbor to be ready. // create the first token Frame sendFrame = new Token(0, 0, 0); byte[] bFrame = sendFrame.ToBinary(); Frame recieveFrame; Frame newToken; Frame frame; // send it! sendStream.Write(bFrame, 0, bFrame.Length); recieveFrame = Frame.MakeFrame(Receive()); Debug.Assert(recieveFrame.DA == this.nodeNum); Debug.Assert(recieveFrame.FS == 2 || recieveFrame.FS == 3); try { while (true) { // listen state // recieve frame, check if token frame = Frame.MakeFrame(Receive()); if (frame is Token) { // if it was sent by the monitor, everyone is done sending if (frame.SA == this.nodeNum) { // send a frame with the finished bit enabled sendFrame = new Frame(2, 255, 0, null); bFrame = sendFrame.ToBinary(); sendStream.Write(bFrame, 0, bFrame.Length); } // if the token wasn't sent by the monitor, must send ack else { sendFrame = new Frame(0, frame.SA, this.nodeNum, null); sendFrame.FS = 2; bFrame = sendFrame.ToBinary(); sendStream.Write(bFrame, 0, bFrame.Length); } // otherwise send a new token if the SA is not the monitor newToken = new Token(0, this.nodeNum, this.nodeNum); bFrame = newToken.ToBinary(); sendStream.Write(bFrame, 0, bFrame.Length); frame = Frame.MakeFrame(Receive()); if (frame.SA == this.nodeNum) { // send a frame with the kill bit enabled sendFrame = new Frame(2, lastNode, 0, null); bFrame = sendFrame.ToBinary(); sendStream.Write(bFrame, 0, bFrame.Length); } else { Debug.Assert(frame.DA == this.nodeNum); Debug.Assert(frame.FS == 2 || frame.FS == 3); } } // otherwise, check if the bridge is telling it to shutdown else if (frame.AC == 1) { Console.WriteLine("Exterminate list"); // send a frame with the kill bit enabled sendFrame = new Frame(1, lastNode, 0, null); bFrame = sendFrame.ToBinary(); sendStream.Write(bFrame, 0, bFrame.Length); break; } else { bFrame = frame.ToBinary(); sendStream.Write(bFrame, 0, bFrame.Length); } } } finally { // Close all open resources (i.e. sockets!) Console.WriteLine("Monitor node EX-TERM-INATED!"); this.recieveStream.Close(); this.recieveClient.Close(); } }
// what runs on startup of node public virtual void Run() { int destRing = -1; bool shouldTransmit = false; bool shutdown; // connect with neighboring nodes this.Connect(); Console.WriteLine(this.nodeNum + "Connected"); lock (logLocker) { logFile.WriteLine(DateTime.Now.ToString() + " Connected with token ring " + this.bridgeNumber); } Random rand = new Random(); byte[] bFrame; // Accept incoming connection and wait for // right neighbor to be ready. try { while (true) { // listen state // recieve frame, check if token Frame frame = Frame.MakeFrame(Receive()); if (frame is Token) { // check to see if the thread's buffer has something to transmit if (bridgeNumber == 1) { lock (buf1Locker) { if (buffer1.Count != 0) shouldTransmit = true; else shouldTransmit = false; } } else { lock (buf2Locker) { if (buffer2.Count != 0) shouldTransmit = true; else shouldTransmit = false; } } // if it does, enter transmit state if (shouldTransmit) { Transmit(frame); } else { // otherwise, send the token along bFrame = frame.ToBinary(); this.sendStream.Write(bFrame, 0, bFrame.Length); } } // shutdown signal. else if (frame.AC == 2 || frame.DA == 255) { Console.WriteLine(this.bridgeNumber + " is ready to shutdown"); lock (logLocker) { logFile.WriteLine(DateTime.Now.ToString() + " Token ring " + this.bridgeNumber + " is ready to shutdown"); } // figure out if the other side is ready to shutdown lock (shutdownLocker) { shutdown = shouldShutdown; if (!shouldShutdown) shouldShutdown = true; } // if not ready to shutdown, go into infinite send state until a shutdown signal comes through the buffer if (!shutdown) { while (true) { // check to see if the thread's buffer has something to transmit if (bridgeNumber == 1) { lock (buf1Locker) { if (buffer1.Count != 0) shouldTransmit = true; else shouldTransmit = false; } } else { lock (buf2Locker) { if (buffer2.Count != 0) shouldTransmit = true; else shouldTransmit = false; } } if (shouldTransmit) { if (shutdownTransmit()) { break; // shutdown } else Thread.Sleep(10); // otherwise, sleep for 10 ms } else { Thread.Sleep(10); // if nothing in the queue, sleep and try again } } break; } // otherwise, send shutdown signal to both rings and shutdown else { frame = new Frame(1, 0, 255, null); if (bridgeNumber == 1) { lock (buf2Locker) { buffer2.Enqueue(new Frame(frame.AC, frame.DA, frame.SA, frame.data)); } bFrame = frame.ToBinary(); this.sendStream.Write(bFrame, 0, bFrame.Length); } else { lock (buf1Locker) { buffer1.Enqueue(new Frame(frame.AC, frame.DA, frame.SA, frame.data)); } bFrame = frame.ToBinary(); this.sendStream.Write(bFrame, 0, bFrame.Length); } } break; } // send the frame to the proper ring else { // check for which ring the frame goes to lock (lookupTableLocker) { if (lookupTable.Contains(frame.DA)) destRing = (int)lookupTable[frame.DA]; else destRing = -1; } // if it is unknown, add it to both buffers if (destRing == -1) { // set the bit to be checked later for adding to lookup table frame.AC = 4; // add it to both buffers lock (buf1Locker) { buffer1.Enqueue(new Frame(frame.AC, frame.DA, frame.SA, frame.data)); } lock (buf2Locker) { buffer2.Enqueue(new Frame(frame.AC, frame.DA, frame.SA, frame.data)); } // setup "faked" ack frame.FS = 2; // frame accepted frame.AC = 0; // reset the AC bit to avoid confusion } // if it is known, add it to that buffer else { if (destRing == 1) { lock (buf1Locker) { buffer1.Enqueue(new Frame(frame.AC, frame.DA, frame.SA, frame.data)); } if (this.bridgeNumber != destRing) { lock (logLocker) { logFile.WriteLine(DateTime.Now.ToString() + " Sending frame to Token Ring " + destRing + ". Source=" + frame.SA + " Destination=" + frame.DA); } } } else { lock (buf2Locker) { buffer2.Enqueue(new Frame(frame.AC, frame.DA, frame.SA, frame.data)); } if (this.bridgeNumber != destRing) { lock (logLocker) { logFile.WriteLine(DateTime.Now.ToString() + " Sending frame to Token Ring " + destRing + ". Source=" + frame.SA + " Destination=" + frame.DA); } } } // setup "faked" ack frame.FS = 2; } // send ack bFrame = frame.ToBinary(); this.sendStream.Write(bFrame, 0, bFrame.Length); } } } finally { // Close all open resources (i.e. sockets!) Console.WriteLine(this.nodeNum + " " + this.bridgeNumber + " Exterminate!"); lock (logLocker) { logFile.WriteLine(DateTime.Now.ToString() + " Token ring " + this.bridgeNumber + " is shutting down"); } if (this.bridgeNumber == 1) { Thread.Sleep(20); lock (logLocker) { logFile.Close(); } } this.recieveStream.Close(); this.recieveClient.Close(); } }