/// <summary>
        /// Reads settings.
        /// </summary>
        /// <param name="properties">Settings container to read from.</param>
        protected virtual void ReadSettings(IDictionary properties)
        {
            // retrieve settings
            foreach (DictionaryEntry entry in properties)
            {
                if (string.Compare(entry.Key.ToString(), "name", true) == 0)
                {
                    this._channelName = entry.Value.ToString();
                }

                if (string.Compare(entry.Key.ToString(), "priority", true) == 0)
                {
                    this._channelPriority = GenuineUtility.SafeConvertToInt32(entry.Value, this._channelPriority);
                }

                if (string.Compare(entry.Key.ToString(), "prefix", true) == 0)
                {
                    this._urlPrefix = entry.Value.ToString();
                    if (!this._urlPrefix.StartsWith("g") || this._urlPrefix.Length < 4 || this._urlPrefix.Length > 8)
                    {
                        GenuineExceptions.Get_Channel_InvalidParameter("prefix");
                    }
                }
            }

            // enable compresion if such an option is specified
            if ((bool)this.ITransportContext.IParameterProvider[GenuineParameter.Compression])
            {
                this.SecuritySessionParameters = SecuritySessionServices.DefaultContextWithCompression;
            }

#if DEBUG
            try
            {
                // enable logging
                if (this.ITransportContext.IParameterProvider[GenuineParameter.EnableGlobalLoggingToFile] is string &&
                    ((string)this.ITransportContext.IParameterProvider[GenuineParameter.EnableGlobalLoggingToFile]).Length > 0)
                {
                    GenuineLoggingServices.SetUpLoggingToFile(this.ITransportContext.IParameterProvider[GenuineParameter.EnableGlobalLoggingToFile] as string,
                                                              this.ITransportContext.IParameterProvider[GenuineParameter.LoggingParameters] as string);
                }
                else if (this.ITransportContext.IParameterProvider[GenuineParameter.EnableGlobalLoggingToMemory] is int &&
                         ((int)this.ITransportContext.IParameterProvider[GenuineParameter.EnableGlobalLoggingToMemory]) > 0)
                {
                    GenuineLoggingServices.SetUpLoggingToMemory((int)this.ITransportContext.IParameterProvider[GenuineParameter.EnableGlobalLoggingToMemory],
                                                                this.ITransportContext.IParameterProvider[GenuineParameter.LoggingParameters] as string);
                }
            }
            catch
            {
            }
#endif
        }
        /// <summary>
        /// Constructs an instance of the SharedMemoryConnection class.
        /// </summary>
        /// <param name="iTransportContext">The transport context.</param>
        /// <param name="name">The name of the shared chunk.</param>
        /// <param name="isServer">The role.</param>
        /// <param name="setCloseStatusOnExit">Indicates whether it is necessary to set the "closed" status on exit.</param>
        internal SharedMemoryConnection(ITransportContext iTransportContext, string name, bool isServer, bool setCloseStatusOnExit)
        {
            this.ITransportContext     = iTransportContext;
            this.ShareName             = "GenuineChannels_GShMem_" + name;
            this.IsServer              = isServer;
            this._setCloseStatusOnExit = setCloseStatusOnExit;

            this._shareSize            = (int)iTransportContext.IParameterProvider[GenuineParameter.SMShareSize];
            this._pingTimeOut          = GenuineUtility.ConvertToMilliseconds(iTransportContext.IParameterProvider[GenuineParameter.PersistentConnectionSendPingAfterInactivity]);
            this._closeAfterInactivity = GenuineUtility.ConvertToMilliseconds(iTransportContext.IParameterProvider[GenuineParameter.ClosePersistentConnectionAfterInactivity]);

            string localSideName  = (isServer ? "Server" : "Client");
            string remoteSideName = (isServer ? "Client" : "Server");

            IParameterProvider parameters = this.ITransportContext.IParameterProvider;

            // construct shared object names for the local side
            string readCompletedEventName = GenuineSharedMemoryChannel.ConstructSharedObjectName(
                this.ShareName + localSideName + "ReadCompleted", parameters);
            string writeCompletedEventName = GenuineSharedMemoryChannel.ConstructSharedObjectName(
                this.ShareName + localSideName + "WriteCompleted", parameters);

            // construct shared object names for the remote side
            string remoteReadCompletedEventName = GenuineSharedMemoryChannel.ConstructSharedObjectName(
                this.ShareName + remoteSideName + "ReadCompleted", parameters);
            string remoteWriteCompletedEventName = GenuineSharedMemoryChannel.ConstructSharedObjectName(
                this.ShareName + remoteSideName + "WriteCompleted", parameters);

            if (isServer)
            {
                if (this._shareSize < MIN_SHARE_SIZE || this._shareSize > MAX_SHARE_SIZE)
                {
                    throw GenuineExceptions.Get_Channel_InvalidParameter("SMShareSize");
                }

                this.LowLevel_CreateSharedMemory();
                this._closed           = 0;
                this._writtenShareSize = this._shareSize;

                this._receiveOffset    = 5;
                this._sendOffset       = (this._shareSize - 5) / 2;
                this._receiveSpaceSize = this._sendOffset - 5 - 8;
                this._sendSpaceSize    = this._shareSize - this._sendOffset - 8;

                this._namedEventReadCompleted        = NamedEvent.CreateNamedEvent(readCompletedEventName, false, true);
                this._namedEventWriteCompleted       = NamedEvent.CreateNamedEvent(writeCompletedEventName, false, true);
                this._namedEventRemoteReadCompleted  = NamedEvent.CreateNamedEvent(remoteReadCompletedEventName, false, true);
                this._namedEventRemoteWriteCompleted = NamedEvent.CreateNamedEvent(remoteWriteCompletedEventName, false, true);
            }
            else
            {
                this.OpenSharedMemory();

                if (this._closed != 0)
                {
                    throw GenuineExceptions.Get_Connect_CanNotConnectToRemoteHost(name, "Remote host has already closed the connection.");
                }

                this._shareSize = this._writtenShareSize;
                if (this._shareSize < MIN_SHARE_SIZE || this._shareSize > MAX_SHARE_SIZE)
                {
                    throw GenuineExceptions.Get_Channel_InvalidParameter("SMShareSize");
                }

                this._receiveOffset    = (this._shareSize - 5) / 2;
                this._sendOffset       = 5;
                this._receiveSpaceSize = this._shareSize - this._receiveOffset - 8;
                this._sendSpaceSize    = this._receiveOffset - 5 - 8;

                this._namedEventReadCompleted        = NamedEvent.OpenNamedEvent(readCompletedEventName);
                this._namedEventWriteCompleted       = NamedEvent.OpenNamedEvent(writeCompletedEventName);
                this._namedEventRemoteReadCompleted  = NamedEvent.OpenNamedEvent(remoteReadCompletedEventName);
                this._namedEventRemoteWriteCompleted = NamedEvent.OpenNamedEvent(remoteWriteCompletedEventName);
            }

            this._sendBuffer = new byte[this._sendSpaceSize];
        }
Exemple #3
0
        /// <summary>
        /// Starts listening to the specified end point and accepting incoming connections.
        /// </summary>
        /// <param name="endPoint">The end point.</param>
        public override void StartListening(object endPoint)
        {
            BinaryLogWriter binaryLogWriter = this.ITransportContext.BinaryLogWriter;

            this._closing = false;

            // LOG:
            if (binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0)
            {
                binaryLogWriter.WriteConnectionParameterEvent(LogCategory.Connection, "UdpConnectionManager.StartListening",
                                                              LogMessageType.ConnectionParameters, null, null, this.ITransportContext.IParameterProvider,
                                                              GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, this.DbgConnectionId,
                                                              "UDP socket is being associated with the end point: {0}.", endPoint.ToString());
            }

            // get the ip end point
            IPEndPoint ipEndPoint = null;
            int        port;
            string     url;

            try
            {
                url        = (string)endPoint;
                url        = GenuineUtility.SplitToHostAndPort(url, out port);
                ipEndPoint = new IPEndPoint(GenuineUtility.ResolveIPAddress(url), port);
            }
            catch (Exception ex)
            {
                // LOG:
                if (binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0)
                {
                    binaryLogWriter.WriteEvent(LogCategory.Connection, "UdpConnectionManager.StartListening",
                                               LogMessageType.ListeningStarted, ex, null, null, null,
                                               GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                                               null, null, this.DbgConnectionId, 0, 0, 0, null, null, null, null,
                                               "The listening socket cannot be associated with the {0} local end point.", endPoint.ToString());
                }

                throw GenuineExceptions.Get_Server_IncorrectAddressToListen(endPoint as string);
            }

            lock (this)
            {
                if (this._socket != null)
                {
                    throw GenuineExceptions.Get_Server_EndPointIsAlreadyBeingListenedTo(this._socket.LocalEndPoint.ToString());
                }

                // initialize the socket
                this._socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
                if (this.ITransportContext.IParameterProvider[GenuineParameter.UdpTtl] != null)
                {
                    this._socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.IpTimeToLive, (int)this.ITransportContext.IParameterProvider[GenuineParameter.UdpTtl]);
                }

                // Receive buffer size
                this._socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveBuffer, (int)this.ITransportContext.IParameterProvider[GenuineParameter.UdpReceiveBuffer]);
                this._socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, 1);

                this._socket.Bind(ipEndPoint);

                // if it's an IP multicast sender
                if (this.ITransportContext.IParameterProvider[GenuineParameter.UdpMulticastTo] != null)
                {
                    try
                    {
                        url = (string)this.ITransportContext.IParameterProvider[GenuineParameter.UdpMulticastTo];
                        url = GenuineUtility.SplitToHostAndPort(url, out port);
                        this._multicastTo = new IPEndPoint(GenuineUtility.ResolveIPAddress(url), port);

                        this._socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1);
                        if (this.ITransportContext.IParameterProvider[GenuineParameter.UdpTtl] != null)
                        {
                            this._socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, (int)this.ITransportContext.IParameterProvider[GenuineParameter.UdpTtl]);
                        }
                    }
                    catch (Exception)
                    {
                        throw GenuineExceptions.Get_Channel_InvalidParameter("UdpMulticastTo");
                    }
                }

                // and join to the specified broadcast network
                if (this.ITransportContext.IParameterProvider[GenuineParameter.UdpJoinTo] != null)
                {
                    string joinTo = (string)this.ITransportContext.IParameterProvider[GenuineParameter.UdpJoinTo];
                    this._socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1);

                    IPAddress       ipAddressToJoinTo = GenuineUtility.ResolveIPAddress(joinTo);
                    MulticastOption multicastOption   = new MulticastOption(ipAddressToJoinTo, ipEndPoint.Address);
                    this._socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, multicastOption);
                }

                // initiate receiving
                Thread receivingThread = new Thread(new ThreadStart(this.ReceiveSynchronously));
                receivingThread.IsBackground = true;
                receivingThread.Start();

                // LOG:
                if (binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0)
                {
                    binaryLogWriter.WriteEvent(LogCategory.Connection, "UdpConnectionManager.StartListening",
                                               LogMessageType.ConnectionEstablished, null, null, null, null,
                                               GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                                               null, null,
                                               this.DbgConnectionId, (int)GenuineConnectionType.Invocation, 0, 0, this.GetType().Name, this._socket.LocalEndPoint.ToString(), null, null,
                                               "The UDP socket is ready for action.");
                }
            }
        }