/// <summary> /// Sends the specified packet using unicast to a specific DJ Tap device. /// </summary> /// <param name="packet">The packet to send on the network.</param> /// <param name="address">The address of the device to send the packet to.</param> protected void Unicast(TCNetPacket packet, TCNetEndPoint address) { MemoryStream data = new MemoryStream(); TCNetBinaryWriter writer = new TCNetBinaryWriter(data); IPEndPoint localEndpoint = (IPEndPoint)nodeSocket.LocalEndPoint; TCNetHeader header = packet as TCNetHeader; if (header != null) { header.NodeID = NodeId; header.NodeType = Role; header.NodeName = NodeName; header.SequenceNumber = NextSequenceNumber(); header.Timestamp = DateTime.UtcNow.TimeOfDay; TraceEventType traceLevel = TraceEventType.Information; DataTypes dataType = DataTypes.None; TCNetDataHeader dataHeader = header as TCNetDataHeader; if (dataHeader != null) { dataType = dataHeader.DataType; } tcNetTrace.TraceEvent(traceLevel, (int)header.MessageType, $"{header.NodeName}: {header.GetType().Name} {(dataType != DataTypes.None ? dataType.ToString() : string.Empty)}"); } packet.WriteData(writer); try { unicastTXSocket.SendTo(data.ToArray(), new IPEndPoint(address.Address, address.Port)); } catch (SocketException ex) { OnUnhandledException(new TCNetSocketException(this, "Socket error unicast TCNet integration.", ex)); } }
/// <summary> /// Unicasts a TCNet packet to the specified device. /// </summary> /// <param name="endPoint">The IP address and port to send the packet to.</param> /// <param name="packet">The packet to be unicast.</param> public void Send(TCNetEndPoint endPoint, TCNetPacket packet) { Unicast(packet, endPoint); }
/// <summary> /// Unicasts a TCNet packet to the specified device. /// </summary> /// <param name="device">The device to send the packet to.</param> /// <param name="packet">The packet to be unicast.</param> public void Send(TCNetDevice device, TCNetPacket packet) { Send(device.Endpoint, packet); }
/// <summary> /// Called when when new data is recieved on a socket. /// </summary> /// <param name="state">The recieve data for this transaction.</param> private void OnRecieve(IAsyncResult state) { EndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, 0); if (PortOpen) { TCNetRecieveData recieveState = (TCNetRecieveData)(state.AsyncState); if (recieveState != null) { try { IPEndPoint localEndpoint = (IPEndPoint)recieveState.Socket.LocalEndPoint; SocketError socketError; int dataRecieved; dataRecieved = recieveState.Socket.EndReceiveFrom(state, ref remoteEndPoint); recieveState.SetLength((recieveState.Length - recieveState.ReadNibble) + dataRecieved); //Protect against UDP loopback where we recieve our own packets. if (localEndpoint != remoteEndPoint && recieveState.Valid) { LastPacket = DateTime.UtcNow; TCNetPacket newPacket; while (TCNetPacketBuilder.TryBuild(recieveState, (DateTime)LastPacket, out newPacket)) { recieveState.ReadPosition = (int)recieveState.Position; newPacket.NetworkID = TCNetPacket.BuildNetworkID((IPEndPoint)remoteEndPoint, newPacket.NodeID); //Packet has been read successfully. if (NewPacket != null) { NewPacket(this, new NewPacketEventArgs <TCNetPacket>(new TCNetEndPoint((IPEndPoint)remoteEndPoint, newPacket.NodeID), newPacket)); } } } } catch (ObjectDisposedException ex) { //It is possible for the socket to become disposed OnUnhandledException(ex); PortOpen = false; } catch (Exception ex) { OnUnhandledException(ex); } finally { //Attempt to recieve another packet. if (PortOpen) { StartRecieve(recieveState.Socket, recieveState.Port, recieveState.Unicast); } } } } }
/// <summary> /// Tries to create a packet from the header information. /// </summary> /// <param name="data">The data.</param> /// <param name="timeStamp">The time stamp.</param> /// <param name="packet">The packet.</param> /// <returns></returns> internal static bool TryBuild(TCNetRecieveData data, DateTime timeStamp, out TCNetPacket packet) { TCNetHeader header = new TCNetHeader(MessageTypes.None); packet = header; try { //We have read all the data. if (data.EndOfData()) { data.Reset(); return(false); } //Check we have enough data to construct the header. if (data.Length - data.ReadPosition < TCNetHeader.PacketSize) { return(false); } //Read the packet header. header.ReadData(data.GetReader()); //Ensure the header packet is valid if (!header.IsValid()) { //Purge data as it is probably corrupted. data.Reset(); //Reset position to start so we dump the data. return(false); } //Read the sub packet Func <TCNetPacket> create; switch (header.MessageType) { case MessageTypes.Data: { TCNetDataHeader dataHeader = new TCNetDataHeader(DataTypes.None); //Read the packet header. dataHeader.ReadData(data.GetReader()); if (!registeredDataPackets.TryGetValue(dataHeader.DataType, out create)) { return(false); } } break; case MessageTypes.ApplicationSpecificData: { TCNetApplicationSpecificData dataHeader = new TCNetApplicationSpecificData(); //Read the packet header. dataHeader.ReadData(data.GetReader()); if (!registeredApplicationPackets.TryGetValue(dataHeader.ApplicationSignature, out create)) { return(false); } } break; default: if (!registeredPackets.TryGetValue(header.MessageType, out create)) { return(false); } break; } //Create the sub packet packet = create(); packet.RXTimeStamp = timeStamp; packet.ReadData(data.GetReader()); } catch (EndOfStreamException) { return(false); } return(packet != null); }