BeginReceive() public method

public BeginReceive ( AsyncCallback requestCallback, object state ) : IAsyncResult
requestCallback AsyncCallback
state object
return IAsyncResult
Beispiel #1
0
        /// <inheritdoc />
        protected override void StartIncomingDataListen()
        {
#if WINDOWS_PHONE || NETFX_CORE
            throw new NotImplementedException("Not needed for UDP connections on Windows Phone 8");
#else
            if (NetworkComms.ConnectionListenModeUseSync)
            {
                if (incomingDataListenThread == null)
                {
                    incomingDataListenThread              = new Thread(IncomingUDPPacketWorker);
                    incomingDataListenThread.Priority     = NetworkComms.timeCriticalThreadPriority;
                    incomingDataListenThread.Name         = "UDP_IncomingDataListener";
                    incomingDataListenThread.IsBackground = true;
                    incomingDataListenThread.Start();
                }
            }
            else
            {
                if (asyncListenStarted)
                {
                    throw new ConnectionSetupException("Async listen already started. Why has this been called twice?.");
                }

                udpClient.BeginReceive(new AsyncCallback(IncomingUDPPacketHandler), udpClient);

                asyncListenStarted = true;
            }
#endif
        }
Beispiel #2
0
        /// <summary>
        /// Incoming data listen async method
        /// </summary>
        /// <param name="ar">Call back state data</param>
        private void IncomingUDPPacketHandler(IAsyncResult ar)
        {
            try
            {
                UdpClientWrapper client         = (UdpClientWrapper)ar.AsyncState;
                IPEndPoint       remoteEndPoint = new IPEndPoint(IPAddress.None, 0);
                byte[]           receivedBytes  = client.EndReceive(ar, ref remoteEndPoint);

                //Received data after comms shutdown initiated. We should just close the connection
                if (NetworkComms.commsShutdown)
                {
                    CloseConnection(false, -13);
                }

                if (NetworkComms.LoggingEnabled)
                {
                    NetworkComms.Logger.Trace("Received " + receivedBytes.Length.ToString() + " bytes via UDP from " + remoteEndPoint.Address + ":" + remoteEndPoint.Port.ToString() + ".");
                }

                UDPConnection        connection;
                HandshakeUDPDatagram possibleHandshakeUDPDatagram = new HandshakeUDPDatagram(receivedBytes);
                if (isIsolatedUDPConnection)
                {
                    //This connection was created for a specific remoteEndPoint so we can handle the data internally
                    connection = this;
                }
                else
                {
                    ConnectionInfo desiredConnection = new ConnectionInfo(ConnectionType.UDP, remoteEndPoint, udpClient.LocalIPEndPoint, ConnectionInfo.ApplicationLayerProtocol, ConnectionInfo.ConnectionListener);
                    try
                    {
                        //Look for an existing connection, if one does not exist we will create it
                        //This ensures that all further processing knows about the correct endPoint
                        connection = GetConnection(desiredConnection, ConnectionUDPOptions, ConnectionDefaultSendReceiveOptions, false, this, possibleHandshakeUDPDatagram);
                    }
                    catch (ConnectionShutdownException)
                    {
                        if ((ConnectionUDPOptions & UDPOptions.Handshake) == UDPOptions.Handshake)
                        {
                            if (NetworkComms.LoggingEnabled)
                            {
                                NetworkComms.Logger.Trace("Attempted to get connection " + desiredConnection + " but this caused a ConnectionShutdownException. Exception caught and ignored as should only happen if the connection was closed shortly after being created.");
                            }
                            connection = null;
                        }
                        else
                        {
                            throw;
                        }
                    }
                }

                if (connection != null && !possibleHandshakeUDPDatagram.DatagramHandled)
                {
                    //We pass the data off to the specific connection
                    //Lock on the packetbuilder locker as we may receive UDP packets in parallel from this host
                    lock (connection.packetBuilder.Locker)
                    {
                        if (NetworkComms.LoggingEnabled)
                        {
                            NetworkComms.Logger.Trace(" ... " + receivedBytes.Length.ToString() + " bytes added to packetBuilder for " + connection.ConnectionInfo + ". Cached " + connection.packetBuilder.TotalBytesCached.ToString() + " bytes, expecting " + connection.packetBuilder.TotalBytesExpected.ToString() + " bytes.");
                        }

                        connection.packetBuilder.AddPartialPacket(receivedBytes.Length, receivedBytes);
                        if (connection.packetBuilder.TotalBytesCached > 0)
                        {
                            connection.IncomingPacketHandleHandOff(connection.packetBuilder);
                        }

                        if (connection.packetBuilder.TotalPartialPacketCount > 0)
                        {
                            LogTools.LogException(new Exception("Packet builder had " + connection.packetBuilder.TotalBytesCached + " bytes remaining after a call to IncomingPacketHandleHandOff with connection " + connection.ConnectionInfo + ". Until sequenced packets are implemented this indicates a possible error."), "UDPConnectionError");
                        }
                    }
                }

                client.BeginReceive(new AsyncCallback(IncomingUDPPacketHandler), client);
            }
            //On any error here we close the connection
            catch (NullReferenceException)
            {
                CloseConnection(true, 25);
            }
            catch (ArgumentNullException)
            {
                CloseConnection(true, 36);
            }
            catch (IOException)
            {
                CloseConnection(true, 26);
            }
            catch (ObjectDisposedException)
            {
                CloseConnection(true, 27);
            }
            catch (SocketException)
            {
                //Receive may throw a SocketException ErrorCode=10054  after attempting to send a datagram to an unreachable target.
                //We will try to get around this by ignoring the ICMP packet causing these problems on client creation
                CloseConnection(true, 28);
            }
            catch (InvalidOperationException)
            {
                CloseConnection(true, 29);
            }
            catch (ConnectionSetupException)
            {
                //Can occur if data is received as comms is being shutdown.
                //Method will attempt to create new connection which will throw ConnectionSetupException.
                CloseConnection(true, 50);
            }
            catch (Exception ex)
            {
                LogTools.LogException(ex, "Error_UDPConnectionIncomingPacketHandler");
                CloseConnection(true, 30);
            }
        }