/// <summary> /// Инициализирует экземпляр класса. /// </summary> /// <param name="appIDByte">Идентификатор приложения для FLAPHeader.ID</param> /// <param name="events">Набор событий, которые будут использованы этим экземпляром OSCARUdp</param> /// <param name="acceptsIncomingConnections"> /// Значение True указывает, что этот экземпляр OSCARUdp может принимать входящие соединения. /// В противном случае запросы на подключения из-вне будут игнорироваться. /// </param> public OSCARUdp(byte appIDByte, OSCARCallbacks events, bool acceptsIncomingConnections) : base(appIDByte, events, new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp), false) { m_needsBind = true; m_acceptsIncomingConnections = acceptsIncomingConnections; this.Connections = new List<EndPoint>(1); m_svcFlap = new FLAPHeader(appIDByte, 0, 0); }
private bool readPacket(ref FLAPHeader flap, out byte[] data, out EndPoint from) { from = null; if (m_socket.Available >= FLAPHeader.FullLength) { var header = new byte[FLAPHeader.FullLength]; IPPacketInformation ipInfo; SocketFlags flags = SocketFlags.None; from = new IPEndPoint(IPAddress.Any, 0); m_socket.ReceiveMessageFrom(header, 0, FLAPHeader.FullLength, ref flags, ref from, out ipInfo); ushort flapDataLength = 0; flap = FLAPHeader.FromBytes(header, out flapDataLength, base.AppIDByte); data = new byte[flapDataLength]; if (flapDataLength > 0) m_socket.ReceiveFrom(data, 0, flapDataLength, SocketFlags.None, ref from); return true; } data = null; return false; }
public void Send(OSCARUdp self, ref FLAPHeader f) { var tlvs = new TLVChain(2) { new TLV { TypeID = SvcLayer.TLV_TYPE, Value = new byte[1] { SvcLayer.TYPE_CONNECT_REQST }}, new TLV{TypeID = SvcLayer.TLV_CONNECT_HASH, Value = Hash } }; self.queuePacket(ref self.m_svcFlap, (byte[])tlvs, Host); AttemptsTaken++; LastSent = Environment.TickCount; }
private void queuePacket(ref FLAPHeader flap, byte[] data, EndPoint to) { var toSend = new OSCARQueueEntity { FLAP = flap, Data = data, Host = to }; toSend.FLAP.ID = AppIDByte; toSend.FLAP.SequenceNumber = m_localSequence++; m_sendBuffer.Enqueue(toSend); }
private void HandlePacket(ref FLAPHeader flap, byte[] data, IPEndPoint from) { var tlvs = (TLVChain)data; var type = tlvs[SvcLayer.TLV_TYPE].Value[0]; switch(type) { case SvcLayer.TYPE_USER_DATA: if (Connections.Contains(from)) m_events.TriggerPacketReceived(this, new PacketEventArgs(from, ref flap, tlvs[SvcLayer.TLV_USER_DATA].Value)); break; case SvcLayer.TYPE_CONNECT_ACCEPT: if (IsConnecting && m_connReq.Host.Equals(from) && Misc.CompareByteArrays(m_connReq.Hash, tlvs[SvcLayer.TLV_CONNECT_HASH].Value)) { m_connReq = null; Connections.Add(from); m_events.Connected(this, new HostConnectEventArgs(from, true)); } break; case SvcLayer.TYPE_CONNECT_REQST: if (m_acceptsIncomingConnections && (!this.IsConnecting || m_connReq.Host != from) && m_events.AuthorizeIncomingConnection(this, new HostEventArgs(from)) && !this.Connections.Contains(from)) { var tosend = new TLVChain(2) { new TLV { TypeID = SvcLayer.TLV_TYPE, Value = new byte[1] { SvcLayer.TYPE_CONNECT_ACCEPT } }, new TLV { TypeID = SvcLayer.TLV_CONNECT_HASH, Value = tlvs[SvcLayer.TLV_CONNECT_HASH].Value } }; sendPacket(from, ref flap, (byte[])tosend); Connections.Add(from); m_events.Connected(this, new HostConnectEventArgs(from, false)); } break; } }
/// <summary> /// Этот метод не поддерживается, используйте другую перегрузку Send(). /// </summary> /// <param name="flap"></param> /// <param name="data"></param> public override void Send(ref FLAPHeader flap, byte[] data) { throw new NotSupportedException(); }
/// <summary> /// Позволяет получить следующий доступный пакет, переданный этому пиру. /// </summary> /// <param name="block">True для блокирования вызывающего кода, до тех пор, пока пакет не будет получен.</param> /// <param name="flap">Заголовок пакета</param> /// <param name="data">Данные пакета</param> /// <param name="from">Запишет адрес отправителя полученного пакета по в указанную переменную</param> /// <returns>True, если пакет получен.</returns> public bool Receive(bool block, ref FLAPHeader flap, ref byte[] data, ref EndPoint from) { #if DEBUG if (this.Connections.Count == 0) throw new InvalidOperationException("There are no connected peers, cannot Receive()!"); #endif throw new NotImplementedException(); }
/// <summary> /// Не поддерживается. /// </summary> /// <param name="flap"></param> /// <param name="data"></param> /// <param name="block"></param> /// <param name="blockTimeOut"></param> public override bool Receive(ref FLAPHeader flap, out byte[] data, bool block, int blockTimeOut) { throw new NotSupportedException(); }