예제 #1
0
 /// <summary>
 /// Fragments the given message into a number of smaller messages for sending over the network
 /// </summary>
 /// <returns>An array of network mesages belonging which are the fragments of the given message</returns>
 public NetworkMessage[] Fragment(NetworkMessage message)
 {
     List<byte[]> fragments = new List<byte[]>();
      NetworkMessage[] messages;
      int numRead = 1;
      using (MemoryStream ms = new MemoryStream(message.GzData))
      {
     while (numRead > 0)
     {
        byte[] readBytes = new byte[FragmentSize];
        numRead = ms.Read(readBytes, 0, FragmentSize);
        if (numRead > 0)
        {
           if (numRead < FragmentSize)
           {
              byte[] fragData = new byte[numRead];
              Array.Copy(readBytes, fragData, numRead);
              fragments.Add(fragData);
           }
           else
           {
              fragments.Add(readBytes);
           }
        }
     }
     messages = new NetworkMessage[fragments.Count];
     for (int i = 0; i < fragments.Count; i++)
     {
        NetworkMessage fragmentMessage = new NetworkMessage(message.SenderID, message.DestinationID, message.MessageID, message.Type,
           fragments[i], i, fragments.Count, message.Lifetime);
        messages[i] = fragmentMessage;
     }
      }
      return messages;
 }
예제 #2
0
        /// <summary>
        /// Stores a message fragment, if all the fragments of a message are stored MessageDefragmented event is fired
        /// </summary>
        public void Defragment(NetworkMessage message)
        {
            NetworkMessage[] buffer;
             List<int> fragmentsNeededList = null;
             Debug.WriteLine("Fragment: " + message.FragmentNumber + " size: " + message.Data.Length);
             if (incomingFragmentBuffer.ContainsKey(message.MessageID))
             {
            // first fragment has already been received so add to existing buffer
            buffer = (NetworkMessage[])incomingFragmentBuffer[message.MessageID];
             }
             else
             {
            // This is the first fragement of a message received, so create a new buffer
            buffer = new NetworkMessage[message.FragmentTotal];
            messageFragmentsRequired[message.MessageID] = new List<int>(message.FragmentTotal);
            for (int i = 0; i < message.FragmentTotal; i++)
            {
               ((List<int>) messageFragmentsRequired[message.MessageID]).Add(i);
            }
            messageExpiryTimes.Add(new TickGuid(message.MessageID, message.Lifetime));
             }
             fragmentsNeededList = (List<int>) messageFragmentsRequired[message.MessageID];
             buffer[message.FragmentNumber] = message;
             incomingFragmentBuffer[message.MessageID] = buffer;

             fragmentsNeededList.Remove(message.FragmentNumber);

             if (fragmentsNeededList.Count == 0)
             {
            byte[] messageData;
            using (MemoryStream ms = new MemoryStream())
            {
               for (int j = 0; j < buffer.Length; j++)
               {
                  ms.Write(buffer[j].Data, 0, buffer[j].Data.Length);
               }
               messageData = new byte[ms.Length];
               messageData = ms.ToArray();
            }
            MessageDefragmented(this, new MessageDefragmentedEventArgs(buffer[0].DestinationID, buffer[0].SenderID, buffer[0].MessageID, messageData));
            incomingFragmentBuffer.Remove(message.MessageID);
            messageFragmentsRequired.Remove(message.MessageID);
             }
             else
             {
            startMessageLifetimeTimer();
             }
        }
예제 #3
0
        private void MessageLifetimeTimerTimeout(object ob)
        {
            Debug.WriteLine("MessageLifetimeTimerTimeout happened");
             lock (messageExpiryTimes)
             {
            List<TickGuid> expired = messageExpiryTimes.FindAll(earlierThanNow);

            Guid[] guids = new Guid[expired.Count];
            foreach (TickGuid item in expired)
            {
               // check if it's fragments being sent in messageCache
               if (outgoingFragments.ContainsKey(item.id))
               {
                  Debug.WriteLine(String.Format("Expiring from fragment store {0}", item.id));
                  outgoingFragments.Remove(item.id);
               }
               if (incomingFragmentBuffer.ContainsKey(item.id))
               {
                  NetworkMessage[] messageFragments = (NetworkMessage[])incomingFragmentBuffer[item.id];
                  for (int i = 0; i < messageFragments.Length; i++)
                  {
                     if (messageFragments[i] == null)
                     {
                        Debug.WriteLine(String.Format("Need to request resend of message {0} fragment {1}", item.id, i));
                        NetworkMessage message = new NetworkMessage(localID, Guid.Empty, Guid.NewGuid(), NetworkMessageType.FragmentRequest, item.id.ToByteArray(), i, 1, 5000);
                        sendMessage(message);
                     }
                  }
               }
               messageExpiryTimes.Remove(item);
               //Schedule next time to try
               messageExpiryTimes.Add(new TickGuid(item.id, 5000));
            }
             }
             if (messageExpiryTimes.Count == 0)
             {
            if (messageLifetimeTimer != null)
            {
               messageLifetimeTimer.Dispose();
               messageLifetimeTimer = null;
            }
             }
        }
 public MessageEventArgs(NetworkMessage message)
 {
     this.gzData = message.GzData;
      this.senderID = message.SenderID;
      this.destinationID = message.DestinationID;
 }
예제 #5
0
 public void FireMessageReceived(NetworkMessage message)
 {
     if (this.MessageReceived != null)
      {
     MessageReceived(this, new MessageEventArgs(message));
      }
 }
예제 #6
0
 private void sendMessage(NetworkMessage message)
 {
     SendQueue.Enqueue(message);
      messageToSendEvent.Set();
 }
예제 #7
0
 private void ReceiveThread()
 {
     try
      {
     udpReceiveClient = new UdpClient(port, AddressFamily.InterNetwork);
     IPEndPoint receivedFrom = new IPEndPoint(IPAddress.Any, 0);
     byte[] receivedBytes = new byte[100000];
     while (keepRecieving)
     {
        receivedBytes = udpReceiveClient.Receive(ref receivedFrom);
        int receivedLength = receivedBytes.Length;
        if (receivedLength > 36)
        {
           NetworkMessage message = new NetworkMessage(receivedBytes);
           Debug.WriteLine(String.Format("Received {0} from {1}", message.Type, receivedFrom));
           switch (message.Type)
           {
              case NetworkMessageType.Message:
                 ReceiveQueue.Enqueue(message);
                 messageReceivedEvent.Set();
                 break;
              case NetworkMessageType.DirectRequest:
                 if (message.DestinationID == this.localID)
                 {
                    Debug.WriteLine("Received direct request for " + message.DestinationID.ToString());
                    NetworkMessage replyMessage = new NetworkMessage(this.localID, message.SenderID, Guid.NewGuid(), NetworkMessageType.DirectReply, message.Data, 1, 1, 50000);
                    sendMessage(replyMessage);
                 }
                 break;
              case NetworkMessageType.DirectReply:
                 if (message.DestinationID == localID)
                 {
                    Debug.WriteLine("Recieved reply for " + message.DestinationID.ToString());
                    MessageRequest messageReq = new MessageRequest();
                    messageReq.Address = receivedFrom.Address;
                    messageReq.MessageID = new Guid(message.Data);
                    messageReq.Fragment = -1;
                    directUdpTargets.Enqueue(messageReq);
                    directUdpEvent.Set();
                 }
                 break;
              case NetworkMessageType.FragmentRequest:
                 if (message.SenderID != localID)
                 {
                    Guid messageRequestID = new Guid(message.Data);
                    Debug.WriteLine(String.Format("Request for resend of message {0} fragment {1}", messageRequestID, message.FragmentNumber));
                    MessageRequest fragmentReq = new MessageRequest();
                    fragmentReq.Address = receivedFrom.Address;
                    fragmentReq.MessageID = new Guid(message.Data);
                    fragmentReq.Fragment = message.FragmentNumber;
                    directUdpTargets.Enqueue(fragmentReq);
                    directUdpEvent.Set();
                    Thread.Sleep(0);
                 }
                 break;
           }
        }
     }
      }
      catch (SocketException ex)
      {
     Debug.WriteLine(String.Format("SocketException: {0} {1}\r\n{2}", ex.ErrorCode, ex.Message, ex.StackTrace));
      }
 }
예제 #8
0
        public void SendFragments(byte[] data, Guid destinationID)
        {
            Guid messageID = Guid.NewGuid();
             Debug.WriteLine("Created message " + messageID.ToString());
             // Make the lifetime of the message 30 seconds
             NetworkMessage largeMessage = new NetworkMessage(localID, destinationID, messageID, NetworkMessageType.Message,
            data, 1,1, 300000);
             NetworkMessage[] fragments = this.Fragment(largeMessage);
             outgoingFragments[largeMessage.MessageID] = fragments;
             //double the lifetime in send cache so that receivers have a chance to request fragments within one timespan before it's expired
             messageExpiryTimes.Add(new TickGuid(largeMessage.MessageID, (largeMessage.Lifetime*2)));

             Debug.WriteLine("Message fragmented in " + fragments.Length + " fragments.");
             foreach (NetworkMessage message in fragments)
             {
            sendMessage(message);
            Thread.Sleep(0);
             }
             startMessageLifetimeTimer();
        }
예제 #9
0
        public void SendDirect(byte[] data, Guid destinationID)
        {
            Guid messageID = Guid.NewGuid();
             NetworkMessage[] fragments = null;
             TickGuid expiryTime = new TickGuid();
             expiryTime.id = messageID;

             NetworkMessage message = new NetworkMessage(localID, destinationID, messageID, NetworkMessageType.Message,
            data, 1, 1, 10000);

             if (message.GzData.Length > FragmentSize)
             {
            message.Lifetime = 30000;
            //Break the message up if it's large
            fragments = this.Fragment(message);
            expiryTime.SetExpityTime(message.Lifetime);
             }
             else
             {
            fragments = new NetworkMessage[1];
            fragments[0] = message;
            expiryTime.SetExpityTime(message.Lifetime);
             }

             Debug.WriteLine(String.Format("Adding {0} to store in {1} fragments", messageID, fragments.Length));
             outgoingFragments[messageID] = fragments;
             messageExpiryTimes.Add(expiryTime);

             // make the lifetime of the direct request message 5 seconds
             NetworkMessage directRequestMessage = new NetworkMessage(localID, destinationID, Guid.NewGuid(), NetworkMessageType.DirectRequest, messageID.ToByteArray(), 1, 1, 5000);
             sendMessage(directRequestMessage);
             startMessageLifetimeTimer();
        }
예제 #10
0
 public void Send(byte[] bytes, Guid destinationID)
 {
     NetworkMessage message = new NetworkMessage(localID, destinationID, Guid.NewGuid(), NetworkMessageType.Message, bytes, 1, 1, 50000);
      if (message.GzData.Length > FragmentSize)
      {
     // This is a large message, break into fragments
     SendFragments(bytes, destinationID);
      }
      else
      {
     Debug.WriteLine("Created message " + message.MessageID.ToString());
     sendMessage(message);
      }
 }
 public MessageDefragmentedEventArgs(NetworkMessage message)
     : base(message)
 {
     this.gzData = message.Data;
 }