public BeginReceive ( AsyncCallback requestCallback, object state ) : IAsyncResult | ||
requestCallback | AsyncCallback | |
state | object | |
return | IAsyncResult |
/// <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 }
/// <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); } }