/// <summary> /// Dispose per the IDisposable pattern /// </summary> public void Dispose() { GC.SuppressFinalize(this); if (!disposed) { disposed = true; if (sock != null) { // if we are using a reflector, send a tear-down message if (!multicastEP.Equals(nextHopEP)) { try { if (joiner != null) { joiner.Terminate(); } // send a LEAVE message; this might get lost, but that doesn't matter // because the reflector wil time out. UdpSender sender = new UdpSender(nextHopEP, 64); UdpReflectorMessage message = new UdpReflectorMessage(UdpReflectorMessageType.LEAVE, multicastEP); sender.Send(message.ToBufferChunk()); sender.Dispose(); } catch (Exception) { } } LstSocks.Socket.ReleaseSharedSocket(nextHopEP, sock); sock = null; } } }
/// <summary> /// Send UDP join messages to the reflector. There is no acknoweledgement, so we send /// a series of these messages, pausing briefly in between. /// /// A bit of ugliness: the joiner works over both C#'s built in socket, as well as CXP's /// UDPSender. If the class was initialized without a Socket, then we create a locale UdpSender. /// This is necessary because the client uses UdpSender, whereas the reflector uses raw sockets. /// </summary> private void SendJoinMessages() { Debug.Assert(reflectorEP != null); Debug.Assert(multicastEP != null); UdpSender sender = null; try { sender = new UdpSender(this.reflectorEP, 64); sender.DisableLoopback(); while (alive) { UdpReflectorMessage rjm = new UdpReflectorMessage(UdpReflectorMessageType.JOIN, multicastEP); BufferChunk bufferChunk = rjm.ToBufferChunk(); // UdpSender, as used by CXPClient sender.Send(bufferChunk); Thread.Sleep(JOIN_MESSAGE_DELAY); } } catch { } finally { if (sender != null) sender.Dispose(); } }
/// <summary> /// Send UDP join messages to the reflector. There is no acknoweledgement, so we send /// a series of these messages, pausing briefly in between. /// /// A bit of ugliness: the joiner works over both C#'s built in socket, as well as CXP's /// UDPSender. If the class was initialized without a Socket, then we create a locale UdpSender. /// This is necessary because the client uses UdpSender, whereas the reflector uses raw sockets. /// </summary> private void SendJoinMessages() { Debug.Assert(reflectorEP != null); Debug.Assert(multicastEP != null); UdpSender sender = null; try { sender = new UdpSender(this.reflectorEP, 64); sender.DisableLoopback(); while (alive) { UdpReflectorMessage rjm = new UdpReflectorMessage(UdpReflectorMessageType.JOIN, multicastEP); BufferChunk bufferChunk = rjm.ToBufferChunk(); // UdpSender, as used by CXPClient sender.Send(bufferChunk); Thread.Sleep(JOIN_MESSAGE_DELAY); } } catch { } finally { if (sender != null) { sender.Dispose(); } } }
/// <summary> /// Dispose per the IDisposable pattern /// </summary> public void Dispose() { GC.SuppressFinalize(this); if(!disposed) { disposed = true; if (sock != null) { // if we are using a reflector, send a tear-down message if (!multicastEP.Equals(nextHopEP)) { try { if (joiner != null) joiner.Terminate(); // send a LEAVE message; this might get lost, but that doesn't matter // because the reflector wil time out. UdpSender sender = new UdpSender(nextHopEP, 64); UdpReflectorMessage message = new UdpReflectorMessage(UdpReflectorMessageType.LEAVE, multicastEP); sender.Send(message.ToBufferChunk()); sender.Dispose(); } catch (Exception) { } } LstSocks.Socket.ReleaseSharedSocket(nextHopEP, sock); sock = null; } } }
private void CheckForReflector() { // send a ping UdpReflectorMessage ping = new UdpReflectorMessage(UdpReflectorMessageType.PING); BufferChunk buffer = ping.ToBufferChunk(); reflectorSocket.SendTo(buffer.Buffer, buffer.Index, buffer.Length, SocketFlags.None, ReflectorAddress); // wait for response byte [] byteBuffer = new byte[512]; int count = reflectorSocket.Receive(byteBuffer); UdpReflectorMessage pingReply = new UdpReflectorMessage(byteBuffer,count); if (pingReply.Type == UdpReflectorMessageType.PING_REPLY) { this.ReportProgress(100); this.lastSuccessfulReading = DateTime.Now; } // wait a bit... Thread.Sleep(1500); }
public void ProcessMessage(UdpReflectorMessage message,IPEndPoint source,Socket localSocket) { IPEndPoint localEP = localSocket.LocalEndPoint as IPEndPoint; if (message.Type == UdpReflectorMessageType.LEAVE) { // a background thread will eventually remove the multicast group, if necessary lock (clientRegTable) { clientRegTable.Remove(source); } return; } else if (message.Type == UdpReflectorMessageType.JOIN) { IPEndPoint multicastEP = message.MulticastEP; JoinMulticastGroup(multicastEP); subscribedMulticastGroups[multicastEP.Address] = multicastEP.Address; ClientEntry entry = new ClientEntry(source, multicastEP, DateTime.Now); lock (clientRegTable) { clientRegTable.Add(source, entry); } // Multi-reflector cascading join, if required. We send an identical join request on the // same port to the parent's IP address if (ParentReflector != null) { IPEndPoint parentEP = new IPEndPoint(ParentReflector, localEP.Port); UdpReflectorMessage joinMessage = new UdpReflectorMessage(UdpReflectorMessageType.JOIN, multicastEP); BufferChunk chunk = joinMessage.ToBufferChunk(); localSocket.SendTo(chunk.Buffer, chunk.Index, chunk.Length, SocketFlags.None,parentEP); // Need to add the parent to our local dispatch table (to simulate a remote join) ClientEntry parentEntry = new ClientEntry(parentEP, multicastEP, DateTime.Now); lock (clientRegTable) { clientRegTable.Add(parentEP, parentEntry); } } } else if (message.Type == UdpReflectorMessageType.PING) { // acknowledge that we're alive... UdpReflectorMessage pingReply = new UdpReflectorMessage(UdpReflectorMessageType.PING_REPLY); BufferChunk bufferChunk = pingReply.ToBufferChunk(); localSocket.SendTo(bufferChunk.Buffer, bufferChunk.Index, bufferChunk.Length, SocketFlags.None, source); } else { // unknown or unhandled message type... } }