use of io.netty.channel.socket.DatagramPacket in project netty by netty.
the class EpollDatagramChannel method recvmsg.
private boolean recvmsg(EpollRecvByteAllocatorHandle allocHandle, NativeDatagramPacketArray array, ByteBuf byteBuf) throws IOException {
RecyclableArrayList datagramPackets = null;
try {
int writable = byteBuf.writableBytes();
boolean added = array.addWritable(byteBuf, byteBuf.writerIndex(), writable);
assert added;
allocHandle.attemptedBytesRead(writable);
NativeDatagramPacketArray.NativeDatagramPacket msg = array.packets()[0];
int bytesReceived = socket.recvmsg(msg);
if (bytesReceived == 0) {
allocHandle.lastBytesRead(-1);
return false;
}
byteBuf.writerIndex(bytesReceived);
InetSocketAddress local = localAddress();
DatagramPacket packet = msg.newDatagramPacket(byteBuf, local);
if (!(packet instanceof io.netty.channel.unix.SegmentedDatagramPacket)) {
processPacket(pipeline(), allocHandle, bytesReceived, packet);
byteBuf = null;
} else {
// Its important that we process all received data out of the NativeDatagramPacketArray
// before we call fireChannelRead(...). This is because the user may call flush()
// in a channelRead(...) method and so may re-use the NativeDatagramPacketArray again.
datagramPackets = RecyclableArrayList.newInstance();
addDatagramPacketToOut(packet, datagramPackets);
// null out byteBuf as addDatagramPacketToOut did take ownership of the ByteBuf / packet and transfered
// it into the RecyclableArrayList.
byteBuf = null;
processPacketList(pipeline(), allocHandle, bytesReceived, datagramPackets);
datagramPackets.recycle();
datagramPackets = null;
}
return true;
} finally {
releaseAndRecycle(byteBuf, datagramPackets);
}
}
use of io.netty.channel.socket.DatagramPacket in project netty by netty.
the class EpollDatagramChannel method addDatagramPacketToOut.
private static void addDatagramPacketToOut(DatagramPacket packet, RecyclableArrayList out) {
if (packet instanceof io.netty.channel.unix.SegmentedDatagramPacket) {
io.netty.channel.unix.SegmentedDatagramPacket segmentedDatagramPacket = (io.netty.channel.unix.SegmentedDatagramPacket) packet;
ByteBuf content = segmentedDatagramPacket.content();
InetSocketAddress recipient = segmentedDatagramPacket.recipient();
InetSocketAddress sender = segmentedDatagramPacket.sender();
int segmentSize = segmentedDatagramPacket.segmentSize();
do {
out.add(new DatagramPacket(content.readRetainedSlice(Math.min(content.readableBytes(), segmentSize)), recipient, sender));
} while (content.isReadable());
segmentedDatagramPacket.release();
} else {
out.add(packet);
}
}
use of io.netty.channel.socket.DatagramPacket in project netty by netty.
the class EpollDatagramUnicastTest method testSegmentedDatagramPacket.
private void testSegmentedDatagramPacket(Bootstrap sb, Bootstrap cb, boolean composite, boolean gro) throws Throwable {
if (!(cb.group() instanceof EpollEventLoopGroup)) {
// Only supported for the native epoll transport.
return;
}
if (gro && !(sb.group() instanceof EpollEventLoopGroup)) {
// Only supported for the native epoll transport.
return;
}
assumeTrue(EpollDatagramChannel.isSegmentedDatagramPacketSupported());
Channel sc = null;
Channel cc = null;
try {
cb.handler(new SimpleChannelInboundHandler<Object>() {
@Override
public void channelRead0(ChannelHandlerContext ctx, Object msgs) {
// Nothing will be sent.
}
});
cc = cb.bind(newSocketAddress()).sync().channel();
final int numBuffers = 16;
final int segmentSize = 512;
int bufferCapacity = numBuffers * segmentSize;
final CountDownLatch latch = new CountDownLatch(numBuffers);
AtomicReference<Throwable> errorRef = new AtomicReference<Throwable>();
if (gro) {
// Enable GRO and also ensure we can read everything with one read as otherwise
// we will drop things on the floor.
sb.option(EpollChannelOption.UDP_GRO, true);
sb.option(ChannelOption.RCVBUF_ALLOCATOR, new FixedRecvByteBufAllocator(bufferCapacity));
}
sc = sb.handler(new SimpleChannelInboundHandler<DatagramPacket>() {
@Override
public void channelRead0(ChannelHandlerContext ctx, DatagramPacket packet) {
if (packet.content().readableBytes() == segmentSize) {
latch.countDown();
}
}
}).bind(newSocketAddress()).sync().channel();
if (sc instanceof EpollDatagramChannel) {
assertEquals(gro, sc.config().getOption(EpollChannelOption.UDP_GRO));
}
InetSocketAddress addr = sendToAddress((InetSocketAddress) sc.localAddress());
final ByteBuf buffer;
if (composite) {
CompositeByteBuf compositeBuffer = Unpooled.compositeBuffer();
for (int i = 0; i < numBuffers; i++) {
compositeBuffer.addComponent(true, Unpooled.directBuffer(segmentSize).writeZero(segmentSize));
}
buffer = compositeBuffer;
} else {
buffer = Unpooled.directBuffer(bufferCapacity).writeZero(bufferCapacity);
}
cc.writeAndFlush(new io.netty.channel.unix.SegmentedDatagramPacket(buffer, segmentSize, addr)).sync();
if (!latch.await(10, TimeUnit.SECONDS)) {
Throwable error = errorRef.get();
if (error != null) {
throw error;
}
fail();
}
} finally {
if (cc != null) {
cc.close().sync();
}
if (sc != null) {
sc.close().sync();
}
}
}
use of io.netty.channel.socket.DatagramPacket in project reactor-netty by reactor.
the class Application method main.
public static void main(String[] args) {
Connection server = UdpServer.create().handle((in, out) -> out.sendObject(in.receiveObject().map(o -> {
if (o instanceof DatagramPacket) {
DatagramPacket p = (DatagramPacket) o;
ByteBuf buf = Unpooled.copiedBuffer("hello", CharsetUtil.UTF_8);
// <1>
return new DatagramPacket(buf, p.sender());
} else {
return Mono.error(new Exception("Unexpected type of the message: " + o));
}
}))).bindNow(Duration.ofSeconds(30));
server.onDispose().block();
}
use of io.netty.channel.socket.DatagramPacket in project reactor-netty by reactor.
the class Application method main.
public static void main(String[] args) {
UdpServer udpServer = UdpServer.create().handle((in, out) -> out.sendObject(in.receiveObject().map(o -> {
if (o instanceof DatagramPacket) {
DatagramPacket p = (DatagramPacket) o;
return new DatagramPacket(p.content().retain(), p.sender());
} else {
return Mono.error(new Exception("Unexpected type of the message: " + o));
}
})));
// <1>
udpServer.warmup().block();
Connection server = udpServer.bindNow(Duration.ofSeconds(30));
server.onDispose().block();
}
Aggregations