コード例 #1
0
        public override void Bind(EndPoint localEP)
        {
            if (this.ActsAsServer)
            {
                throw new Exception("Cannot call {nameof(Bind)} multiple times.");
            }

            UnderlyingSocket.Bind(localEP);

            this.ActsAsServer = true;
            this.Clients      = new ConcurrentDictionary <IPEndPoint, UdpSocket>();
            this.ServerTaskCancellationTokenSource = new CancellationTokenSource();

            // All "receives" should be handled by this "server" instance.  For now, let's try one background thread.
            ServerTask = Task.Run(async() =>
            {
                try
                {
                    var buffer = new byte[4096];

                    while (true)
                    {
                        // TODO: There should be a TTL on "acting as server" sockets that are "connected" to remote endpoints, since
                        // UDP clients won't ever request a "close".
                        var receive        = await UnderlyingSocket.ReceiveFromAsync(buffer, SocketFlags.None, new IPEndPoint(IPAddress.Any, 0 /* any */));
                        var read           = receive.ReceivedBytes;
                        var remoteEndpoint = (IPEndPoint)receive.RemoteEndPoint;

                        var memory = new byte[read].AsMemory();
                        buffer.AsMemory().Slice(0, read).CopyTo(memory);

                        // See if this is for a "client" socket; if so, queue up for that socket's receive.

                        if (Clients.TryGetValue(remoteEndpoint, out UdpSocket? actualReceiver))
                        {
                            await actualReceiver.AwaitingReceives.Writer.WriteAsync(memory, ServerTaskCancellationTokenSource.Token);
                            continue;
                        }

                        // Otherwise, queue up for "self" in awaiting accepts.

                        var acceptingSocket = new UdpSocket(UnderlyingSocket)
                        {
                            TrackedRemote = remoteEndpoint
                        };
                        await acceptingSocket.AwaitingReceives.Writer.WriteAsync(memory);

                        await this.AwaitingAccepts.Writer.WriteAsync(acceptingSocket, ServerTaskCancellationTokenSource.Token);
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message);
                    throw e;
                }
            }, ServerTaskCancellationTokenSource.Token);
        }
コード例 #2
0
 public override void Dispose()
 {
     if (!this.ActsAsServer)
     {
         return; // NO-OP for client sockets.
     }
     this.Disconnect(false);
     UnderlyingSocket.Dispose();
 }
コード例 #3
0
 /// <summary>
 /// Marks a specific connection for graceful shutdown. The next receive or send to be posted
 /// will fail and close the connection.
 /// </summary>
 public void Shutdown(SocketShutdown socketShutdown)
 {
     try
     {
         trace.Debug("Shutting Down Socket to {0} Side = {1}", IPAddress, socketShutdown.ToString());
         UnderlyingSocket.Shutdown(socketShutdown);
     }
     catch (Exception e)
     {
         trace.Error(e, "Non-fatal error shuttind down socket");
     }
 }
コード例 #4
0
        private void ReceiveAsyncLoop(ReceiveAsyncState receiveState)
        {
receiveAsyncLoopAgain:
            if (receiveState.countToRead > 0)
            {
                receiveEventArgs.SetBuffer(receiveState.byteBuffer.WriteOffset, receiveState.countToRead);
                if (UnderlyingSocket.ReceiveAsync(receiveEventArgs) == false)
                {
                    // completed synchrounsly
                    CompleteReceive(receiveEventArgs, false);
                    goto receiveAsyncLoopAgain;
                }
            }
        }
コード例 #5
0
        private void SendAsyncLoop(SendAsyncState sendState)
        {
sendAsyncLoopAgain:
            if (sendState.countToWrite > 0)
            {
                sendEventArgs.SetBuffer(sendState.byteBuffer.ReadOffset, sendState.countToWrite);
                if (UnderlyingSocket.SendAsync(sendEventArgs) == false)
                {
                    // completed synchrounsly
                    CompleteSend(sendEventArgs, false);
                    goto sendAsyncLoopAgain;
                }
            }
        }
コード例 #6
0
        public override void Disconnect(bool reuseSocket)
        {
            if (!ActsAsServer)
            {
                return; // NO-OP for "client" sockets.
            }
            // Clear all clients.
            this.Clients?.Clear();

            // Cancel listening thread.
            ServerTaskCancellationTokenSource?.Cancel();

            // Disconnect underlying socket.
            UnderlyingSocket.Disconnect(reuseSocket);
        }
コード例 #7
0
 public void Close()
 {
     try
     {
         try
         {
             UnderlyingSocket.Shutdown(SocketShutdown.Both);
         }
         catch (Exception e)
         {
             trace.Error(e, "Non-fatal error shutting down socket");
         }
         UnderlyingSocket.Close();
     }
     finally
     {
         var onClosedEvent = OnClosed;
         if (onClosedEvent != null)
         {
             onClosedEvent(this, EventArgs.Empty);
         }
     }
 }
コード例 #8
0
 public bool ReceiveAsync(SocketAsyncEventArgs args)
 {
     return(UnderlyingSocket.ReceiveAsync(args));
 }
コード例 #9
0
 public override ValueTask <int> SendAsync(ReadOnlyMemory <byte> buffer, CancellationToken cancellationToken = default) =>
 UnderlyingSocket.SendAsync(buffer, SocketFlags.None);
コード例 #10
0
        public override async Task <TransportSocket> ConnectAsync(IPAddress address, int port)
        {
            await UnderlyingSocket.ConnectAsync(address, port);

            return(this);
        }
コード例 #11
0
 public override async Task <TransportSocket> AcceptAsync() =>
 (await UnderlyingSocket.AcceptAsync()).ToTcpSocket();
コード例 #12
0
 public override ValueTask <int> ReceiveAsync(Memory <byte> buffer, CancellationToken cancellationToken = default) =>
 UnderlyingSocket.ReceiveAsync(buffer, SocketFlags.None, cancellationToken);
コード例 #13
0
 public override void Bind(EndPoint localEP) =>
 UnderlyingSocket.Bind(localEP);
コード例 #14
0
 public override void Disconnect(bool reuseSocket) =>
 UnderlyingSocket.Disconnect(reuseSocket);
コード例 #15
0
 public bool SendAsync(SocketAsyncEventArgs args)
 {
     return(UnderlyingSocket.SendAsync(args));
 }
コード例 #16
0
 public override void Dispose() => UnderlyingSocket.Dispose();
コード例 #17
0
 public override ValueTask <int> SendAsync(ReadOnlyMemory <byte> buffer, CancellationToken cancellationToken = default)
 {
     return(new ValueTask <int>(UnderlyingSocket.SendToAsync(buffer.ToArray(), SocketFlags.None, TrackedRemote)));
 }
コード例 #18
0
 public bool ConnectAsync(SocketAsyncEventArgs args)
 {
     return(UnderlyingSocket.ConnectAsync(args));
 }
コード例 #19
0
 public void Dispose()
 {
     UnderlyingSocket.Dispose();
 }
コード例 #20
0
 public int Receive(IList <ArraySegment <byte> > buffers)
 {
     return(UnderlyingSocket.Receive(buffers));
 }
コード例 #21
0
 public override void Listen(int backlog) =>
 UnderlyingSocket.Listen(backlog);
コード例 #22
0
 public int Send(IList <ArraySegment <byte> > buffers)
 {
     return(UnderlyingSocket.Send(buffers));
 }
コード例 #23
0
        public override async Task <TransportSocket> ConnectAsync(string host, int port)
        {
            await UnderlyingSocket.ConnectAsync(host, port);

            return(this);
        }