/// <summary> /// Initializes a new instance of the <see cref="UdpServer"/> class. /// </summary> /// <param name="configString">Configuration string of the <see cref="UdpServer"/>. See <see cref="DefaultConfigurationString"/> for format.</param> public UdpServer(string configString) : base(TransportProtocol.Udp, configString) { m_clientIdentificationMode = DefaultClientIdentificationMode; m_allowDualStackSocket = DefaultAllowDualStackSocket; m_maxSendQueueSize = DefaultMaxSendQueueSize; m_clientInfoLookup = new ConcurrentDictionary <Guid, UdpClientInfo>(); m_sendHandler = (sender, args) => ProcessSend(args); m_receiveHandler = (sender, args) => ProcessReceive(args); }
/// <summary> /// Starts the <see cref="UdpServer"/> synchronously and begins accepting client connections asynchronously. /// </summary> /// <exception cref="InvalidOperationException">Attempt is made to <see cref="Start()"/> the <see cref="UdpServer"/> when it is running.</exception> public override void Start() { if (CurrentState == ServerState.NotRunning) { ClientIdentificationMode clientIdentificationMode; int maxSendQueueSize; // Initialize if uninitialized if (!Initialized) Initialize(); // Overwrite config file if client identification mode exists in connection string. if (m_configData.ContainsKey("identifyClientsBy") && Enum.TryParse(m_configData["identifyClientsBy"], true, out clientIdentificationMode)) m_clientIdentificationMode = clientIdentificationMode; // Overwrite config file if client end points are dynamic if (m_configData.ContainsKey("dynamicClientEndPoints")) m_dynamicClientEndPoints = m_configData["dynamicClientEndPoints"].ParseBoolean(); // Overwrite config file if max send queue size exists in connection string. if (m_configData.ContainsKey("maxSendQueueSize") && int.TryParse(m_configData["maxSendQueueSize"], out maxSendQueueSize)) m_maxSendQueueSize = maxSendQueueSize; // Bind server socket to local end-point m_udpServer = new TransportProvider<Socket>(); m_udpServer.SetReceiveBuffer(ReceiveBufferSize); m_udpServer.Provider = Transport.CreateSocket(m_configData["interface"], int.Parse(m_configData["port"]), ProtocolType.Udp, m_ipStack, m_allowDualStackSocket); m_udpServer.Provider.ReceiveBufferSize = ReceiveBufferSize; // Disable SocketError.ConnectionReset exception from being thrown when the endpoint is not listening // Fix MONO bug with SIO_UDP_CONNRESET try { m_udpServer.Provider.IOControl(SIO_UDP_CONNRESET, new[] { Convert.ToByte(false) }, null); } catch { } // Notify that the server has been started successfully OnServerStarted(); if ((object)m_udpServer.Provider.LocalEndPoint != null) { m_receiveArgs = FastObjectFactory<SocketAsyncEventArgs>.CreateObjectFunction(); m_receiveArgs.SocketFlags = SocketFlags.None; m_receiveArgs.Completed += m_receiveHandler; ReceivePayloadAsync(m_receiveArgs); } // Determine whether we have a static or dynamic client list m_dynamicClientList = !m_configData.ContainsKey("clients"); if (m_dynamicClientList) { m_dynamicClientEndPoints = true; } else { // We process the static list of clients. foreach (string clientString in m_configData["clients"].Replace(" ", "").Split(',')) { try { Match endpoint = Regex.Match(clientString, Transport.EndpointFormatRegex); int port; if (endpoint != Match.Empty) AddUdpClient(endpoint.Groups["host"].Value, int.Parse(endpoint.Groups["port"].Value)); else if (int.TryParse(clientString, out port)) AddUdpClient(null, port); else AddUdpClient(clientString, 0); } catch (Exception ex) { string errorMessage = $"Unable to connect to client {clientString}: {ex.Message}"; OnClientConnectingException(new Exception(errorMessage, ex)); } } } } else { throw new InvalidOperationException("Server is currently running"); } }
/// <summary> /// Initializes a new instance of the <see cref="UdpServer"/> class. /// </summary> /// <param name="configString">Configuration string of the <see cref="UdpServer"/>. See <see cref="DefaultConfigurationString"/> for format.</param> public UdpServer(string configString) : base(TransportProtocol.Udp, configString) { m_clientIdentificationMode = DefaultClientIdentificationMode; m_allowDualStackSocket = DefaultAllowDualStackSocket; m_maxSendQueueSize = DefaultMaxSendQueueSize; m_clientInfoLookup = new ConcurrentDictionary<Guid, UdpClientInfo>(); m_sendHandler = (sender, args) => ProcessSend(args); m_receiveHandler = (sender, args) => ProcessReceive(args); }