private void CompareSwitchMessages(SwitchMessage msg, SwitchMessage msgTwo) { Assert.AreEqual(msg.Destination, msgTwo.Destination); Assert.AreEqual(msg.Sender, msgTwo.Sender); Assert.AreEqual(msg.Ack, msgTwo.Ack); Assert.AreEqual(msg.Info, msgTwo.Info); int len = 0; if (msg.ToSend.Length >= msgTwo.ToSend.Length) { len = msg.ToSend.Length; } else { len = msgTwo.ToSend.Length; } for (int i = 0; i < len; i++) { Assert.AreEqual(msg.ToSend[i], msgTwo.ToSend[i]); } }
/// <summary> /// Sendings this instance. /// </summary> private void SwitchSending() { //try //{ while (!this.Client.Connected) { Thread.SpinWait(100); } NetworkStream stream = this.Client.GetStream(); char[] splitOpt = { ',' }; String[] dstMsg; WriteStream caller = new WriteStream(ParentNode.WriteToNetworkStream); bool resend = true; while (this.toSend.Count > 0) { lock (this.toSend) { dstMsg = this.toSend.Dequeue().Split(splitOpt, 2); } SwitchMessage msg = new SwitchMessage(); msg.EncodeMessage(dstMsg[0], this.ParentNode.Name, dstMsg[1]); //Console.WriteLine(" : " + msg.Info + " : Node " + this.name + " is sending to Node " + dstMsg[0] + " this message " ); while (resend) { lock (stream) { if (stream.CanWrite) { caller.BeginInvoke(stream, msg, null, null); } else { Console.WriteLine("Node " + this.ParentNode.Name + " cannot write via switch."); } } try { //Sleep until an ack is recieved. Thread.Sleep(10000); } catch (ThreadInterruptedException) { resend = false; } if(this.doneSending == true) { resend = false; } } resend = true; if (this.doneSending == true) { break; } } //Console.WriteLine("Sender thread for node " + this.name + " exiting."); SwitchMessage done = new SwitchMessage(); done.EncodeHiddenComm(GlobalConst.serverName, GlobalConst.serverName); this.doneSending = true; while (stream.CanWrite) { try { stream.Write(done.ToSend, 0, done.ToSend.Length); Thread.Sleep(1000); } catch (System.IO.IOException) { break; } catch (ThreadInterruptedException) { ; } } }
/// <summary> /// Listens for this instance. /// </summary> private void SwitchListening() { try { NetworkStream clientStream = this.Client.GetStream(); byte[] message; int bytesRead; WriteStream caller = new WriteStream(this.parentNode.WriteToNetworkStream); while (true) { bytesRead = 0; message = GlobalConst.getSpaceByteArray(GlobalConst.BUFSIZE); lock (this.toSend) { if (this.toSend.Count < 1) { clientStream.ReadTimeout = 30000; } } try { //blocks until a client sends a message bytesRead = clientStream.Read(message, 0, GlobalConst.BUFSIZE); } catch { //a socket error has occured Console.WriteLine("Socket error on node " + this.parentNode.Name); break; } if (bytesRead == 0) { //the client has disconnected from the server Console.WriteLine("Node " + this.parentNode.Name + " has disconnected from the switch."); break; } SwitchMessage msg = new SwitchMessage(); bool msgOk = msg.Decode(message); Console.WriteLine("Got message on switch node " + this.parentNode.Name); if(!msgOk) { } else if (msg.Ack) { if (SenderThread.ThreadState.Equals(ThreadState.WaitSleepJoin)) { //Notify the sender thread that the receiving node did get it. SenderThread.Interrupt(); } else { //Console.WriteLine("Node {0} sent to node {1} (really {2}) an ack when it wasn't supposed to!", msg.Sender, msg.Destination, this.name); } } else { //message has successfully been received parentNode.writeOutMessage(msg); SwitchMessage ackMsg = new SwitchMessage(); ackMsg.EncodeHiddenComm(msg.Sender, msg.Destination); lock (clientStream) { if (clientStream.CanWrite) { caller.BeginInvoke(clientStream, ackMsg, null, null); } else { Console.WriteLine("Node " + this.ParentNode.Name + " can't send an ack."); } } } } } catch (Exception ex) { Console.WriteLine(ex); } if(!this.doneSending) { this.senderThread.Abort(); this.doneSending = true; } this.doneReceiving = true; while(!this.parentThread.ThreadState.Equals(ThreadState.WaitSleepJoin)) { Thread.Sleep(100); } this.parentThread.Interrupt(); //this.client.Close(); }
/// <summary> /// Sends the specified message. /// </summary> /// <param name="msg">The message to SwitchSend.</param> private void send(SwitchMessage msg) { String receiver = msg.Destination; TcpClient from = getTcpClient(msg.Sender); TcpClient client = getTcpClient(receiver); HashSet<TcpClient> alreadySent = new HashSet<TcpClient>(); int i = 0; if (client != null && client.Connected) { actuallySend(client, msg); } else { alreadySent.Add(from); lock (this.unkownNames) { foreach (TcpClient unknown in unkownNames) { if (!alreadySent.Contains(unknown) && unknown.Connected) { actuallySend(unknown, msg); alreadySent.Add(unknown); } else { ; //already in sent set } i++; } } lock (this.knownNames) { i = 0; foreach (TcpClient known in knownNames.Keys) { if (!alreadySent.Contains(known) && known.Connected) { actuallySend(known, msg); alreadySent.Add(known); } else { ; //already in sent set } i++; } } } }
/// <summary> /// Handles the client comm. STarts a new thread for each node. /// </summary> /// <param name="clientObject">The client object.</param> private void HandleClientComm(object clientObject) { try { TcpClient client = (TcpClient)clientObject; NetworkStream clientStream = client.GetStream(); byte[] message; int bytesRead; while (true) { bytesRead = 0; message = GlobalConst.getSpaceByteArray(GlobalConst.BUFSIZE); try { //blocks until a client sends a message bytesRead = clientStream.Read(message, 0, GlobalConst.BUFSIZE); } catch { //a socket error has occured break; } if (bytesRead == 0) { //the client has disconnected from the server //this.nodeDisconnectedCount++; break; } SwitchMessage msg = new SwitchMessage(); bool msgOk = msg.Decode(message); if(!msgOk) { continue; } checkIfKnown(client, msg.Sender); //message has successfully been received try { if (msg.Destination.Equals(GlobalConst.serverName)) { this.nodeDisconnectedCount++; } else { enqueMessage(msg); } } catch { if (msg.Destination == null) { Console.WriteLine("msg.Dest is null."); } else if (GlobalConst.serverName == null) { Console.WriteLine("ServerName is null."); } } } } catch(ThreadInterruptedException) { TcpClient c = (TcpClient)clientObject; c.Close(); } catch (Exception ex) { Console.WriteLine(ex); } }
/// <summary> /// Enques the messages to SwitchSend. /// </summary> /// <param name="msg">The message.</param> private void enqueMessage(SwitchMessage msg) { Queue<SwitchMessage> queue = null; lock (this.msgsToSend) { switch (msg.Priority) { case GlobalConst.PriorityLevels.SUPER: queue = this.msgsToSend[1]; queue.Enqueue(msg); return; case GlobalConst.PriorityLevels.COMMON: default: queue = this.msgsToSend[0]; queue.Enqueue(msg); return; } } }
/// <summary> /// Actually sends the message. /// </summary> /// <param name="client">The client.</param> /// <param name="msg">The message to send.</param> private void actuallySend(TcpClient client, SwitchMessage msg) { //Console.WriteLine(" : " + msg.Info + " : " + "Switch is sending msg to Node " + msg.Destination); try { client.GetStream().Write(msg.ToSend, 0, msg.ToSend.Length); client.GetStream().Flush(); } catch (System.IO.IOException) { ; } }