/// <summary> /// Begin listening for incoming connections. Once this is called, you must call Close before calling Listen again. /// </summary> /// <param name="localEndpoint">The local endpoint to listen on.</param> public void Listen(IPEndPoint localEndpoint, bool discoverable = true, string name = "SimplSocketServer", string description = null) { // Sanitize if (localEndpoint == null) { throw new ArgumentNullException(nameof(localEndpoint)); } lock (_isListeningLock) { if (_isListening) { throw new InvalidOperationException("socket is already in use"); } _isListening = true; } // Create socket _socket = _socketFunc(); _socket.Bind(localEndpoint); _socket.Listen(PredictedConnectionCount); // very important to not have buffer for accept, see remarks on 288 byte threshold: https://msdn.microsoft.com/en-us/library/system.net.sockets.socket.acceptasync(v=vs.110).aspx var socketAsyncEventArgs = new SocketAsyncEventArgs(); socketAsyncEventArgs.Completed += OperationCallback; // Post accept on the listening socket if (!TryUnsafeSocketOperation(_socket, SocketAsyncOperation.Accept, socketAsyncEventArgs)) { lock (_isListeningLock) { _isListening = false; throw new Exception("Socket accept failed"); } } // Spin up the keep-alive Task.Factory.StartNew(KeepAlive); // Start beacon if discoverable _beacon = new Beacon(name, (ushort)localEndpoint.Port); _beacon.BeaconData = description ?? $"name {Dns.GetHostName()} "; _beacon.StartAsync(); //_beacon.Start(); }
private async Task BroadcastProbeAsync() { Debug.WriteLine($"P: Broadcasting probe with discovery port {Beacon.DiscoveryPort}"); var probe = Beacon.Encode(BeaconType).ToArray(); await udp.SendAsync(probe, probe.Length, new IPEndPoint(IPAddress.Broadcast, Beacon.DiscoveryPort)); }