/// <summary> /// Send the specified datagram. /// </summary> public void Send(Buffer buffer, IPEndPoint ip) { if (ip.Address.Equals(IPAddress.Broadcast)) { Broadcast(buffer, ip.Port); return; } buffer.MarkAsUsed(); if (mSocket != null) { buffer.BeginReading(); lock (mOut) { Datagram dg = new Datagram(); dg.buffer = buffer; dg.ip = ip; mOut.Enqueue(dg); if (mOut.Count == 1) { // If it's the first datagram, begin the sending process mSocket.BeginSendTo(buffer.buffer, buffer.position, buffer.size, SocketFlags.None, ip, OnSend, null); } } } else { buffer.Recycle(); throw new InvalidOperationException("The socket is null. Did you forget to call UdpProtocol.Start()?"); } }
/// <summary> /// Receive incoming data. /// </summary> void OnReceive(IAsyncResult result) { if (!isActive) return; int bytes = 0; try { bytes = mSocket.EndReceiveFrom(result, ref mEndPoint); } catch (System.Exception ex) { Error(new IPEndPoint(Tools.localAddress, 0), ex.Message); } if (bytes > 4) { // This datagram is now ready to be processed Buffer buffer = Buffer.Create(); buffer.BeginWriting(false).Write(mTemp, 0, bytes); buffer.BeginReading(4); // The 'endPoint', gets reassigned rather than updated. Datagram dg = new Datagram(); dg.buffer = buffer; dg.ip = (IPEndPoint)mEndPoint; lock (mIn) mIn.Enqueue(dg); } // Queue up the next receive operation if (mSocket != null) { mEndPoint = mDefaultEndPoint; mSocket.BeginReceiveFrom(mTemp, 0, mTemp.Length, SocketFlags.None, ref mEndPoint, OnReceive, null); } }
/// <summary> /// Add an error packet to the incoming queue. /// </summary> public void Error(IPEndPoint ip, string error) { Buffer buffer = Buffer.Create(); buffer.BeginPacket(Packet.Error).Write(error); buffer.EndTcpPacketWithOffset(4); Datagram dg = new Datagram(); dg.buffer = buffer; dg.ip = ip; lock (mIn) mIn.Enqueue(dg); }