public void Run()
        {
            try
            {
                Log.Info(TAG, "Started");
                while (!Thread.Interrupted())
                {
                    int readyChannels = selector.Select();

                    if (readyChannels == 0)
                    {
                        Thread.Sleep(10);
                        continue;
                    }

                    System.Console.WriteLine("UDP In");

                    var keys = selector.SelectedKeys().ToList();

                    foreach (var key in keys)
                    {
                        if (!Thread.Interrupted())
                        {
                            if (key.IsValid && key.IsReadable)
                            {
                                selector.SelectedKeys().Remove(key);

                                ByteBuffer receiveBuffer = ByteBufferPool.acquire();
                                // Leave space for the header
                                receiveBuffer.Position(HEADER_SIZE);

                                DatagramChannel inputChannel = (DatagramChannel)key.Channel();
                                // XXX: We should handle any IOExceptions here immediately,
                                // but that probably won't happen with UDP
                                int readBytes = inputChannel.Read(receiveBuffer);

                                Packet referencePacket = (Packet)key.Attachment();
                                referencePacket.updateUDPBuffer(receiveBuffer, readBytes);
                                receiveBuffer.Position(HEADER_SIZE + readBytes);

                                outputQueue.Offer(receiveBuffer);
                            }
                        }
                    }
                }
            }
            catch (InterruptedException e)
            {
                Log.Info(TAG, "Stopping");
            }
            catch (IOException e)
            {
                Log.Warn(TAG, e.ToString(), e);
            }
        }
예제 #2
0
 private void closeChannel(DatagramChannel channel)
 {
     try
     {
         channel.Close();
     }
     catch (IOException e)
     {
         // Ignore
     }
 }
        public static Channel <Try <Datagram> > ToChannel(this Socket socket, Action <DatagramChannelOptions> configuration = null)
        {
            var options = new DatagramChannelOptions();

            configuration?.Invoke(options);

            var channel = new DatagramChannel(socket, options);

            channel.Start();

            return(channel);
        }
예제 #4
0
        private void handleRead(SelectionKey key)
        {
//        Log.d("MIDIPort2","handleRead");
            DatagramChannel c = (DatagramChannel)key.channel();
            UDPBuffer       b = (UDPBuffer)key.attachment();

            try {
                b.buffer.clear();
                b.socketAddress = c.receive(b.buffer);
                EventBus.getDefault().post(new PacketEvent(new DatagramPacket(b.buffer.array(), b.buffer.capacity(), b.socketAddress)));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
예제 #5
0
        private void handleWrite(SelectionKey key)
        {
            if (!outboundQueue.isEmpty())
            {
//            Log.d("MIDIPort2","handleWrite "+ outboundQueue.size());
                try {
                    DatagramChannel c = (DatagramChannel)key.channel();
                    DatagramPacket  d = outboundQueue.poll();

                    c.send(ByteBuffer.wrap(d.getData()), d.getSocketAddress());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
예제 #6
0
 private void HandleRead(SelectionKey key)
 {
     try
     {
         c = (DatagramChannel)key.Channel();
         b = (UDPBuffer)key.Attachment();
         b.buffer.Clear();
         b.socketAddress = c.Receive(b.buffer);
         b.buffer.Flip();
         b.buffer.Get(buff, 0, b.buffer.Limit());
         MessagingCenter.Send <PacketEvent>(new PacketEvent(new Java.Net.DatagramPacket(buff, b.buffer.Limit(), b.socketAddress)), "PacketEvent");
     }
     catch (Exception e)
     {
         throw new IOException(e.StackTrace);
     }
 }
예제 #7
0
 private void HandleWrite(SelectionKey key)
 {
     if (!(outboundQueue.Count == 0))
     {
         if (DEBUG)
         {
             Log.Debug("MIDIPort2", "handleWrite " + outboundQueue.Count);
         }
         try {
             DatagramChannel c = (DatagramChannel)key.Channel();
             DatagramPacket  d = outboundQueue.Dequeue();
             if (d != null)
             {
                 c.Send(ByteBuffer.Wrap(d.GetData()), d.SocketAddress);
             }
         } catch (IOException e) {
             throw new IOException(e.StackTrace);
         }
     }
 }
예제 #8
0
        public DatagramBlock(Socket socket, DatagramBlockOptions options)
        {
            if (socket == null)
            {
                throw new ArgumentNullException(nameof(socket));
            }

            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }

            taskFactory = new TaskFactory(options.TaskScheduler ?? TaskScheduler.Default);

            channel = new DatagramChannel(socket, new DatagramChannelOptions
            {
                SingleReader = true,
                SingleWriter = true
            });

            inputBuffer = new BufferBlock <Try <Datagram> >(new DataflowBlockOptions
            {
                BoundedCapacity   = options.SendingBufferCapacity ?? 1,
                TaskScheduler     = options.TaskScheduler ?? TaskScheduler.Default,
                CancellationToken = options.CancellationToken ?? CancellationToken.None,
                EnsureOrdered     = false
            });

            outputBuffer = new BufferBlock <Try <Datagram> >(new DataflowBlockOptions
            {
                BoundedCapacity   = options.ReceivingBufferCapacity ?? 1,
                TaskScheduler     = options.TaskScheduler ?? TaskScheduler.Default,
                CancellationToken = options.CancellationToken ?? CancellationToken.None,
                EnsureOrdered     = false
            });

            inputCompletionSource  = new TaskCompletionSource();
            outputCompletionSource = new TaskCompletionSource();
        }
예제 #9
0
        private MIDIPort(int port)
        {
            this.port = port;
            try {
                selector      = Selector.Open();
                channel       = DatagramChannel.Open();
                outboundQueue = new Queue <DatagramPacket>();
//            inboundQueue = new ConcurrentLinkedQueue<DatagramPacket>();

                InetSocketAddress address     = new InetSocketAddress(this.port);
                channel.Socket().ReuseAddress = true;
                channel.ConfigureBlocking(false);
                channel.Socket().Bind(address);

                channel.Register(selector, Operations.Read | Operations.Write, new UDPBuffer());

                Thread newThread = new Thread(new ThreadStart(Run));
                newThread.Start();
            }
            catch (IOException e) {
                e.StackTrace.ToString();
            }
        }
예제 #10
0
        private MIDIPort(int port)
        {
            this.port = port;
            try {
                selector      = Selector.open();
                channel       = DatagramChannel.open();
                outboundQueue = new ConcurrentLinkedQueue <>();
//            inboundQueue = new ConcurrentLinkedQueue<DatagramPacket>();

                InetSocketAddress address = new InetSocketAddress(this.port);
                channel.socket().setReuseAddress(true);
                channel.configureBlocking(false);
                channel.socket().bind(address);

//            channel.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE);
                channel.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE, new UDPBuffer());

                Thread newThread = new Thread(new ThreadStart(Run));
                newThread.Start();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
예제 #11
0
        public void Run()
        {
            Log.Info(TAG, "Started");
            try
            {
                Thread currentThread = Thread.CurrentThread();
                while (true)
                {
                    Packet currentPacket;
                    // TODO: Block when not connected
                    do
                    {
                        currentPacket = (Packet)inputQueue.Poll();
                        if (currentPacket != null)
                        {
                            break;
                        }
                        Thread.Sleep(10);
                    } while (!currentThread.IsInterrupted);

                    if (currentThread.IsInterrupted)
                    {
                        break;
                    }

                    InetAddress destinationAddress = currentPacket.ip4Header.destinationAddress;
                    int         destinationPort    = currentPacket.udpHeader.destinationPort;
                    int         sourcePort         = currentPacket.udpHeader.sourcePort;

                    Java.Lang.String ipAndPort = new Java.Lang.String(destinationAddress.HostAddress + ":" + destinationPort + ":" + sourcePort);

                    System.Console.WriteLine("UDP Out: " + ipAndPort);

                    DatagramChannel outputChannel = (DatagramChannel)channelCache.Get(ipAndPort);

                    if (outputChannel == null)
                    {
                        outputChannel = DatagramChannel.Open();
                        vpnService.Protect(outputChannel.Socket());
                        try
                        {
                            outputChannel.Connect(new InetSocketAddress(destinationAddress, destinationPort));
                        }
                        catch (IOException e)
                        {
                            Log.Error(TAG, "Connection error: " + ipAndPort, e);
                            closeChannel(outputChannel);
                            ByteBufferPool.Release(currentPacket.backingBuffer);
                            continue;
                        }

                        outputChannel.ConfigureBlocking(false);
                        currentPacket.SwapSourceAndDestination();

                        selector.Wakeup();
                        outputChannel.Register(selector, SelectionKey.OpRead, currentPacket);

                        channelCache.Put(ipAndPort, outputChannel);
                    }

                    try
                    {
                        ByteBuffer payloadBuffer = currentPacket.backingBuffer;
                        while (payloadBuffer.HasRemaining)
                        {
                            outputChannel.Write(payloadBuffer);
                        }
                    }
                    catch (IOException e)
                    {
                        Log.Error(TAG, "Network write error: " + ipAndPort, e);
                        channelCache.Remove(ipAndPort);
                        closeChannel(outputChannel);
                    }

                    ByteBufferPool.Release(currentPacket.backingBuffer);
                }
            }
            catch (InterruptedException e)
            {
                Log.Info(TAG, "Stopping");
            }
            catch (IOException e)
            {
                Log.Info(TAG, e.ToString(), e);
            }
            finally
            {
                closeAll();
            }
        }