コード例 #1
0
ファイル: InputTunnelPacket.cs プロジェクト: cnsicau/rrs
        void OnHeaderPacketRead <TState>(PacketData data, object[] args)
        {
            if (data.Completed) // 当前包已使用完
            {
                packet.Dispose();
                trans.Input(OnHeaderInput <TState>, args);
                return;
            }
            source       = data.Buffer;
            sourceSize   = data.Size;
            sourceOffset = 0;

            ContinueConstruct((IOCallback <TState>)args[0], (TState)args[1]);
        }
コード例 #2
0
ファイル: TunnelPipeline.cs プロジェクト: cnsicau/rrs
        void CompleteBufferInput <TState>(IPipeline pipeline, IPacket packet, object[] args)
        {
            reader.SetSource(packet.Buffer, packet.Size);
            packet.Dispose();   // used

            var callback = (IOCompleteCallback <TState>)args[0];
            var state    = (TState)args[1];

            Input(callback, state); //
        }
コード例 #3
0
ファイル: HttpReader.cs プロジェクト: cnsicau/rrs
        /// <summary>
        /// 继续读取报文
        /// </summary>
        /// <typeparam name="TReadState"></typeparam>
        /// <param name="callback"></param>
        /// <param name="state"></param>
        protected void ReadPaket <TReadState>(IOCompleteCallback <TReadState> callback, TReadState state)
        {
            if (packet != null)
            {
                // 存在有效报文继续处理
                if (packetOffset < packet.Size)
                {
                    callback(pipeline, this.packet, state);
                    return;
                }
                packet.Dispose();
            }

            pipeline.Input(OnPacketRead <TReadState>, new object[] { callback, state });
        }
コード例 #4
0
ファイル: TunnelPacketWriter.cs プロジェクト: cnsicau/rrs
 void CompleteTransOutput <TState>(IPipeline pipeline, IPacket packet, int completeSize)
 {
     if (completeSize == outputPacket.Size)
     {
         transPacket.Dispose();
         ((IOCompleteCallback <TState>)callback)(tunnelPipeline, outputPacket, (TState)state);
     }
     else // 未完继续
     {
         var dataSize = Math.Min(BufferPacket.BufferSize, outputPacket.Size - completeSize);
         Array.Copy(outputPacket.Buffer, completeSize, packet.Buffer, 0, dataSize);
         transPacket.Relive(dataSize);
         pipeline.Output(packet, CompleteTransOutput <TState>, dataSize + completeSize);
     }
 }
コード例 #5
0
        /// <summary>
        /// Sends a <see cref="Packet"/> to the provided endPoint. Offers more performance if an identical packet is being sent to multiple peers.
        /// NOTE: Any possible reply will be ignored unless listening for incoming UDP packets.
        /// </summary>
        /// <typeparam name="packetPayloadObjectType">The type of object encapsulated by the provided packet</typeparam>
        /// <param name="packetToSend">The packet to send</param>
        /// <param name="ipEndPoint">The destination IPEndPoint. Supports multicast endpoints.</param>
        /// <param name="sendReceiveOptions">The sendReceiveOptions to use for this send</param>
        /// <param name="applicationLayerProtocol">If enabled NetworkComms.Net uses a custom
        /// application layer protocol to provide useful features such as inline serialisation,
        /// transparent packet transmission, remote peer handshake and information etc. We strongly
        /// recommend you use the NetworkComms.Net application layer protocol.</param>
        public static void SendObject <packetPayloadObjectType>(IPacket packetToSend, IPEndPoint ipEndPoint, SendReceiveOptions sendReceiveOptions, ApplicationLayerProtocolStatus applicationLayerProtocol)
        {
            if (ipEndPoint == null)
            {
                throw new ArgumentNullException("ipEndPoint");
            }
            if (sendReceiveOptions == null)
            {
                throw new ArgumentNullException("sendReceiveOptions");
            }

            if (applicationLayerProtocol == ApplicationLayerProtocolStatus.Undefined)
            {
                throw new ArgumentException("A value of ApplicationLayerProtocolStatus.Undefined is invalid when using this method.", "applicationLayerProtocol");
            }

            if (sendReceiveOptions.Options.ContainsKey("ReceiveConfirmationRequired"))
            {
                throw new ArgumentException("Attempted to use a rouge UDP sender when the provided send receive" +
                                            " options specified the ReceiveConfirmationRequired option, which is unsupported. Please create a specific connection" +
                                            "instance to use this feature.", "sendReceiveOptions");
            }

            //Check the send receive options
            if (applicationLayerProtocol == ApplicationLayerProtocolStatus.Disabled)
            {
                if (sendReceiveOptions.DataSerializer != DPSManager.GetDataSerializer <NullSerializer>())
                {
                    throw new ArgumentException("Attempted to use a rouge UDP sender when the provided send receive" +
                                                " options serialiser was not NullSerializer. Please provide compatible send receive options in order to successfully" +
                                                " instantiate this unmanaged connection.", "sendReceiveOptions");
                }

                if (sendReceiveOptions.DataProcessors.Count > 0)
                {
                    throw new ArgumentException("Attempted to use a rouge UDP sender when the provided send receive" +
                                                " options contains data processors. Data processors may not be used with unmanaged connections." +
                                                " Please provide compatible send receive options in order to successfully instantiate this unmanaged connection.", "sendReceiveOptions");
                }
            }

            List <UDPConnection> connectionsToUse = null;

            //If we are already listening on what will be the outgoing adaptor we can send with that client to ensure reply packets are collected
            //The exception here is the broadcasting which goes out all adaptors
            if (ipEndPoint.Address != IPAddress.Broadcast)
            {
                #region Discover best local endpoint

                //Initialise best local end point as match all
                IPEndPoint bestLocalEndPoint = new IPEndPoint(IPAddress.Any, 0);
                try
                {
                    bestLocalEndPoint = IPTools.BestLocalEndPoint(ipEndPoint);
                    //Set the port to 0 to match all.
                    bestLocalEndPoint.Port = 0;
                }
                catch (SocketException ex)
                {
                    throw new ConnectionSetupException("Attempting to determine the best local endPoint to connect to " + ipEndPoint + " resulted in a socket exception.", ex);
                }
                catch (Exception ex)
                {
                    LogTools.LogException(ex, "BestLocalEndPointError", "Error while attempting to determine the best local end point to contact " + ipEndPoint.ToString());
                }

                #endregion Discover best local endpoint

                #region Check For Existing Local Listener

                List <UDPConnectionListener> existingListeners = Connection.ExistingLocalListeners <UDPConnectionListener>(bestLocalEndPoint);

                for (int i = 0; i < existingListeners.Count; i++)
                {
                    if (existingListeners[i].UDPConnection.ConnectionInfo.ApplicationLayerProtocol == applicationLayerProtocol)
                    {
                        connectionsToUse = new List <UDPConnection> {
                            existingListeners[i].UDPConnection
                        };

                        //Once we have a matching connection we can break
                        break;
                    }
                }

                #endregion Check For Existing Local Listener

                //If we have not picked up an existing listener we need to use/create a rougeSender
                if (connectionsToUse == null)
                {
                    #region Check For Suitable Rouge Sender

                    lock (udpRogueSenderCreationLocker)
                    {
                        if (NetworkComms.commsShutdown)
                        {
                            throw new CommunicationException("Attempting to send UDP packet but NetworkCommsDotNet is in the process of shutting down.");
                        }
                        else
                        {
                            if (!udpRogueSenders.ContainsKey(applicationLayerProtocol) ||
                                !udpRogueSenders[applicationLayerProtocol].ContainsKey(bestLocalEndPoint) ||
                                udpRogueSenders[applicationLayerProtocol][bestLocalEndPoint].ConnectionInfo.ConnectionState == ConnectionState.Shutdown)
                            {
                                //Create a new rogue sender
                                if (NetworkComms.LoggingEnabled)
                                {
                                    NetworkComms.Logger.Trace("Creating UDPRougeSender.");
                                }

                                if (!udpRogueSenders.ContainsKey(applicationLayerProtocol))
                                {
                                    udpRogueSenders.Add(applicationLayerProtocol, new Dictionary <IPEndPoint, UDPConnection>());
                                }

                                IPAddress anyRemoteIP = AnyRemoteIPAddress(ipEndPoint.AddressFamily);
                                udpRogueSenders[applicationLayerProtocol][bestLocalEndPoint] = new UDPConnection(new ConnectionInfo(ConnectionType.UDP, new IPEndPoint(anyRemoteIP, 0), bestLocalEndPoint, applicationLayerProtocol), sendReceiveOptions, UDPConnection.DefaultUDPOptions, false);
                            }

                            connectionsToUse = new List <UDPConnection> {
                                udpRogueSenders[applicationLayerProtocol][bestLocalEndPoint]
                            };
                        }
                    }

                    #endregion Check For Suitable Rouge Sender
                }
            }
            else
            {
                #region Get A Sender On All Interfaces For Broadcast

                lock (udpRogueSenderCreationLocker)
                {
                    //We do something special for broadcasts by selected EVERY adaptor
                    if (NetworkComms.LoggingEnabled)
                    {
                        NetworkComms.Logger.Trace("Getting senders for UDP broadcasting.");
                    }

                    if (!udpRogueSenders.ContainsKey(applicationLayerProtocol))
                    {
                        udpRogueSenders.Add(applicationLayerProtocol, new Dictionary <IPEndPoint, UDPConnection>());
                    }

                    connectionsToUse = new List <UDPConnection>();

                    //This is a broadcast and we need to send the broadcast over every local adaptor
                    List <IPAddress> validLocalIPAddresses = HostInfo.IP.FilteredLocalAddresses();
                    foreach (IPAddress address in validLocalIPAddresses)
                    {
                        IPEndPoint currentLocalIPEndPoint = new IPEndPoint(address, 0);
                        List <UDPConnectionListener> existingListeners = Connection.ExistingLocalListeners <UDPConnectionListener>(currentLocalIPEndPoint);

                        //If there is an existing listener we use that
                        if (existingListeners.Count > 0)
                        {
                            for (int i = 0; i < existingListeners.Count; i++)
                            {
                                if (existingListeners[i].UDPConnection.ConnectionInfo.ApplicationLayerProtocol == applicationLayerProtocol)
                                {
                                    connectionsToUse.Add(existingListeners[i].UDPConnection);

                                    //Once we have a matching connection we can break
                                    break;
                                }
                            }
                        }
                        else
                        {
                            //If not we check the rouge senders
                            if (!udpRogueSenders[applicationLayerProtocol].ContainsKey(currentLocalIPEndPoint) ||
                                udpRogueSenders[applicationLayerProtocol][currentLocalIPEndPoint].ConnectionInfo.ConnectionState == ConnectionState.Shutdown)
                            {
                                IPAddress anyRemoteIP = AnyRemoteIPAddress(currentLocalIPEndPoint.AddressFamily);

                                udpRogueSenders[applicationLayerProtocol][currentLocalIPEndPoint] = new UDPConnection(new ConnectionInfo(ConnectionType.UDP, new IPEndPoint(anyRemoteIP, 0), currentLocalIPEndPoint, applicationLayerProtocol), sendReceiveOptions, UDPConnection.DefaultUDPOptions, false);
                            }

                            connectionsToUse.Add(udpRogueSenders[applicationLayerProtocol][currentLocalIPEndPoint]);
                        }
                    }
                }

                #endregion Get A Sender On All Interfaces For Broadcast
            }

            foreach (UDPConnection connection in connectionsToUse)
            {
                try
                {
                    //This has been commented out for the time being as it made no difference to the broadcast issue
                    //we were investigating at the time we had issues
                    //Use the network broadcast address instead of the global broadcast address where possible
                    //if (ipEndPoint.Address == IPAddress.Broadcast && connection.ConnectionInfo.LocalIPEndPoint.AddressFamily == AddressFamily.InterNetwork)
                    //{
                    //    IPEndPoint ipEndPointToUse = new IPEndPoint(IPTools.GetIPv4NetworkBroadcastAddress(connection.ConnectionInfo.LocalIPEndPoint.Address), ipEndPoint.Port);
                    //    connection.SendPacketSpecific<packetPayloadObjectType>(packetToSend, ipEndPointToUse);
                    //}
                    //else
                    connection.SendPacketSpecific <packetPayloadObjectType>(packetToSend, ipEndPoint);
                }
                catch (SocketException) { /* Ignore any socket exceptions */ }
            }

            //Dispose of the packet
            packetToSend.Dispose();
        }
コード例 #6
0
 void CompleteOutput(IPipeline output, IPacket packet, IPipeline input)
 {
     packet.Dispose();   // used.
     input.Input(CompleteInput, output);
 }