/// <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> /// <param name="unicast">Whether we are recieving unicast or broadcast data.</param> protected void StartRecieve(Socket socket, int port, bool unicast) { try { SocketError socketError; EndPoint localPort = new IPEndPoint(IPAddress.Any, 0); TCNetRecieveData recieveState = new TCNetRecieveData() { Socket = socket, Port = port, Unicast = unicast }; recieveState.SetLength(MaxPacketSize); socket.BeginReceiveFrom(recieveState.GetBuffer(), 0, (int)recieveState.Length, SocketFlags.None, ref localPort, new AsyncCallback(OnRecieve), recieveState); } catch (Exception ex) { OnUnhandledException(new TCNetSocketException(this, "An error ocurred while trying to start recieving TCNet.", 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) { 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); } } } } }