sockets - Java, Netty, TCP and UDP connection integration : No buffer space available for UDP connection -
i have application uses both tcp , udp protocols. main assumption client connects server via tcp protocol , when connection established, udp datagrams being send. have support 2 scenarios of connecting server: - client connects when server running - client connects when server down , retries connection until server starts again
for first scenario works pretty fine: got working both connections. problem second scenario. when client tries few times connect via tcp , connects, udp connection function throws exception:
java.net.socketexception: no buffer space available (maximum connections reached?): bind @ sun.nio.ch.net.bind0(native method) @ sun.nio.ch.net.bind(net.java:344) @ sun.nio.ch.datagramchannelimpl.bind(datagramchannelimpl.java:684) @ sun.nio.ch.datagramsocketadaptor.bind(datagramsocketadaptor.java:91) @ io.netty.channel.socket.nio.niodatagramchannel.dobind(niodatagramchannel.java:192) @ io.netty.channel.abstractchannel$abstractunsafe.bind(abstractchannel.java:484) @ io.netty.channel.defaultchannelpipeline$headcontext.bind(defaultchannelpipeline.java:1080) @ io.netty.channel.abstractchannelhandlercontext.invokebind(abstractchannelhandlercontext.java:430) @ io.netty.channel.abstractchannelhandlercontext.bind(abstractchannelhandlercontext.java:415) @ io.netty.channel.defaultchannelpipeline.bind(defaultchannelpipeline.java:903) @ io.netty.channel.abstractchannel.bind(abstractchannel.java:197) @ io.netty.bootstrap.abstractbootstrap$2.run(abstractbootstrap.java:350) @ io.netty.util.concurrent.singlethreadeventexecutor.runalltasks(singlethreadeventexecutor.java:380) @ io.netty.channel.nio.nioeventloop.run(nioeventloop.java:357) @ io.netty.util.concurrent.singlethreadeventexecutor$2.run(singlethreadeventexecutor.java:116) @ io.netty.util.concurrent.defaultthreadfactory$defaultrunnabledecorator.run(defaultthreadfactory.java:137) @ java.lang.thread.run(thread.java:722) when restart client application without doing server, client connect problems.
what can cause problem?
in below attach source code of classes. source code comes examples placed in official netty project page. thing have midified replaced static variables , functions non-static ones. caused in future need many tcp-udp connections multiple servers.
public final class uptimeclient { static final string host = system.getproperty("host", "192.168.2.193"); static final int port = integer.parseint(system.getproperty("port", "2011")); static final int reconnect_delay = integer.parseint(system.getproperty("reconnectdelay", "5")); static final int read_timeout = integer.parseint(system.getproperty("readtimeout", "10")); private static uptimeclienthandler handler; public void runclient() throws exception { configurebootstrap(new bootstrap()).connect(); } private bootstrap configurebootstrap(bootstrap b) { return configurebootstrap(b, new nioeventloopgroup()); } @override protected object clone() throws clonenotsupportedexception { return super.clone(); //to change body of generated methods, choose tools | templates. } bootstrap configurebootstrap(bootstrap b, eventloopgroup g) { if(handler == null){ handler = new uptimeclienthandler(this); } b.group(g) .channel(niosocketchannel.class) .remoteaddress(host, port) .handler(new channelinitializer<socketchannel>() { @override public void initchannel(socketchannel ch) throws exception { ch.pipeline().addlast(new idlestatehandler(read_timeout, 0, 0), handler); } }); return b; } void connect(bootstrap b) { b.connect().addlistener(new channelfuturelistener() { @override public void operationcomplete(channelfuture future) throws exception { if (future.cause() != null) { handler.starttime = -1; handler.println("failed connect: " + future.cause()); } } }); } } @sharable public class uptimeclienthandler extends simplechannelinboundhandler<object> { uptimeclient client; public uptimeclienthandler(uptimeclient client){ this.client = client; } long starttime = -1; @override public void channelactive(channelhandlercontext ctx) { try { if (starttime < 0) { starttime = system.currenttimemillis(); } println("connected to: " + ctx.channel().remoteaddress()); new quoteofthemomentclient(null).run(); } catch (exception ex) { logger.getlogger(uptimeclienthandler.class.getname()).log(level.severe, null, ex); } } @override public void channelread0(channelhandlercontext ctx, object msg) throws exception { } @override public void usereventtriggered(channelhandlercontext ctx, object evt) { if (!(evt instanceof idlestateevent)) { return; } idlestateevent e = (idlestateevent) evt; if (e.state() == idlestate.reader_idle) { // connection ok there no traffic last period. println("disconnecting due no inbound traffic"); ctx.close(); } } @override public void channelinactive(final channelhandlercontext ctx) { println("disconnected from: " + ctx.channel().remoteaddress()); } @override public void channelunregistered(final channelhandlercontext ctx) throws exception { println("sleeping for: " + uptimeclient.reconnect_delay + 's'); final eventloop loop = ctx.channel().eventloop(); loop.schedule(new runnable() { @override public void run() { println("reconnecting to: " + uptimeclient.host + ':' + uptimeclient.port); client.connect(client.configurebootstrap(new bootstrap(), loop)); } }, uptimeclient.reconnect_delay, timeunit.seconds); } @override public void exceptioncaught(channelhandlercontext ctx, throwable cause) { cause.printstacktrace(); ctx.close(); } void println(string msg) { if (starttime < 0) { system.err.format("[server down] %s%n", msg); } else { system.err.format("[uptime: %5ds] %s%n", (system.currenttimemillis() - starttime) / 1000, msg); } } } public final class quoteofthemomentclient { private serverdata config; public quoteofthemomentclient(serverdata config){ this.config = config; } public void run() throws exception { eventloopgroup group = new nioeventloopgroup(); try { bootstrap b = new bootstrap(); b.group(group) .channel(niodatagramchannel.class) .option(channeloption.so_broadcast, true) .handler(new quoteofthemomentclienthandler()); channel ch = b.bind(0).sync().channel(); ch.writeandflush(new datagrampacket( unpooled.copiedbuffer("qotm?", charsetutil.utf_8), new inetsocketaddress("192.168.2.193", 8193))).sync(); if (!ch.closefuture().await(5000)) { system.err.println("qotm request timed out."); } } catch(exception ex) { ex.printstacktrace(); } { group.shutdowngracefully(); } } } public class quoteofthemomentclienthandler extends simplechannelinboundhandler<datagrampacket> { @override public void channelread0(channelhandlercontext ctx, datagrampacket msg) throws exception { string response = msg.content().tostring(charsetutil.utf_8); if (response.startswith("qotm: ")) { system.out.println("quote of moment: " + response.substring(6)); ctx.close(); } } @override public void exceptioncaught(channelhandlercontext ctx, throwable cause) { cause.printstacktrace(); ctx.close(); } }
if server windows server 2008 (r2 or r2 sp1), problem described , solved this stackoverflow answer refers microsoft kb article #2577795
this issue occurs because of race condition in ancillary function driver winsock (afd.sys) causes sockets leaked. time, issue described in "symptoms" section occurs if available socket resources exhausted.
if server windows server 2003, problem described , solved this stackoverflow answer refers microsoft kb article #196271
the default maximum number of ephemeral tcp ports 5000 in products included in "applies to" section. new parameter has been added in these products. increase maximum number of ephemeral ports, follow these steps...
...which means have run out of ephemeral ports.
Comments
Post a Comment