示例#1
0
        private async Task StartListeningAsync(UdpConnection connection)
        {
            try
            {
                var transportTask = connection.StartAsync();

                await transportTask;

                connection.Dispose();
            }
            catch (Exception ex)
            {
                _logger.LogCritical(ex, $"Unexpected exception in {nameof(UdpTransport)}.{nameof(StartListeningAsync)}.", null);
            }
        }
示例#2
0
        public Task BindAsync()
        {
            List <UdpConnection> connections = new List <UdpConnection>();

            IPEndPoint endPoint = new IPEndPoint(IPAddress.Any, _udpConfiguration.ReceivePort);

            for (var schedulerIndex = 0; schedulerIndex < _numSchedulers; schedulerIndex++)
            {
                try
                {
                    Socket listenSocket = new Socket(endPoint.AddressFamily, SocketType.Dgram, ProtocolType.Udp);

                    Extensions.DisableHandleInheritance(listenSocket);

                    listenSocket.ReceiveBufferSize = _udpConfiguration.ReceiveBufferSize;
                    //listenSocket.SendBufferSize = _udpConfiguration.SendBufferSize;
                    listenSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
                    listenSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.PacketInformation, true);

                    // Kestrel expects IPv6Any to bind to both IPv6 and IPv4
                    if (endPoint.Address == IPAddress.IPv6Any)
                    {
                        listenSocket.DualMode = true;
                    }

                    try
                    {
                        listenSocket.Bind(endPoint);
                    }
                    catch (SocketException e) when(e.SocketErrorCode == SocketError.AddressAlreadyInUse)
                    {
                        ThrowSocketAlreadyInUse(e);
                    }

                    // If requested port was "0", replace with assigned dynamic port.
                    if (endPoint.Port == 0)
                    {
                        endPoint = (IPEndPoint)listenSocket.LocalEndPoint;
                    }

                    var connection = new UdpConnection(listenSocket, _memoryPool, _schedulers[schedulerIndex], _udpConfiguration, _logger, _handlerMapper);
                    connections.Add(connection);

                    // REVIEW: This task should be tracked by the server for graceful shutdown
                    // Today it's handled specifically for http but not for arbitrary middleware
                    _ = StartListeningAsync(connection);
                }
                catch (SocketException ex) when(!_unbinding)
                {
                    _logger.LogError(ex);
                    throw;
                }
            }

            _logger.LogInformation($"Started listening to {endPoint.ToString()} with {_numSchedulers.ToString()} listeners.", null);

            _connections = connections;


            return(Task.CompletedTask);
        }