/// <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(DJTapRecieveData data, DateTime timeStamp, out DJTapPacket packet) { DJTapHeader header = new DJTapHeader(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 < DJTapHeader.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 switch (header.ContentType) { case MessageTypes.GWOffer: packet = new GWOffer(); break; case MessageTypes.Timecode: packet = new Timecode(); break; default: return(false); } packet.TimeStamp = timeStamp; packet.ReadData(data.GetReader()); } catch (EndOfStreamException) { return(false); } return(packet != null); }
/// <summary> /// Starts recieving data on an open socket. /// </summary> /// <param name="socket">The socket to recieve data on.</param> /// <param name="port">The port to recieve data on.</param> protected void StartRecieve(Socket socket, int port) { try { EndPoint localPort = new IPEndPoint(IPAddress.Any, port); DJTapRecieveData recieveState = new DJTapRecieveData() { Socket = socket, Port = port }; recieveState.SetLength(1500); socket.BeginReceiveFrom(recieveState.GetBuffer(), 0, (int)recieveState.Length, SocketFlags.None, ref localPort, new AsyncCallback(OnRecieve), recieveState); } catch (Exception ex) { OnUnhandledException(new ApplicationException("An error ocurred while trying to start recieving ArtNet.", ex)); } }
/// <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) { DJTapRecieveData recieveState = (DJTapRecieveData)(state.AsyncState); if (recieveState != null) { try { recieveState.SetLength((recieveState.Length - recieveState.ReadNibble) + recieveState.Socket.EndReceiveFrom(state, ref remoteEndPoint)); //Protect against UDP loopback where we recieve our own packets. if (LocalEndPoint != remoteEndPoint && recieveState.Valid) { LastPacket = DateTime.UtcNow; DJTapPacket newPacket; while (DJTapPacketBuilder.TryBuild(recieveState, (DateTime)LastPacket, out newPacket)) { recieveState.ReadPosition = (int)recieveState.Position; //Packet has been read successfully. if (NewPacket != null) { NewPacket(this, new NewPacketEventArgs <DJTapPacket>((IPEndPoint)remoteEndPoint, newPacket)); } } } } catch (Exception ex) { OnUnhandledException(ex); } finally { //Attempt to recieve another packet. StartRecieve(recieveState.Socket, recieveState.Port); } } } }