diff --git a/akka-actor-tests/src/test/scala/akka/io/UdpConnectedIntegrationSpec.scala b/akka-actor-tests/src/test/scala/akka/io/UdpConnectedIntegrationSpec.scala index 802b36afa7..cb102d5ce8 100644 --- a/akka-actor-tests/src/test/scala/akka/io/UdpConnectedIntegrationSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/io/UdpConnectedIntegrationSpec.scala @@ -14,7 +14,7 @@ class UdpConnectedIntegrationSpec extends AkkaSpec(""" akka.actor.serialize-creators = on """) with ImplicitSender { - val addresses = temporaryServerAddresses(3, udp = true) + val addresses = temporaryServerAddresses(5, udp = true) def bindUdp(address: InetSocketAddress, handler: ActorRef): ActorRef = { val commander = TestProbe() @@ -69,6 +69,27 @@ class UdpConnectedIntegrationSpec extends AkkaSpec(""" expectMsgType[UdpConnected.Received].data should ===(data2) } + "be able to unbind and bind again successfully" in { + val serverAddress = addresses(3) + val clientAddress = addresses(4) + val server1 = bindUdp(serverAddress, testActor) + + val data1 = ByteString("test") + val client = connectUdp(Some(clientAddress), serverAddress, testActor) + + client ! UdpConnected.Send(data1) + expectMsgType[Udp.Received].data should ===(data1) + + server1 ! Udp.Unbind + expectMsg(Udp.Unbound) + + // Reusing the address + val server2 = bindUdp(serverAddress, testActor) + + client ! UdpConnected.Send(data1) + expectMsgType[Udp.Received].data should ===(data1) + } + } } diff --git a/akka-actor/src/main/scala/akka/io/UdpListener.scala b/akka-actor/src/main/scala/akka/io/UdpListener.scala index 239f572f9f..96708869fc 100644 --- a/akka-actor/src/main/scala/akka/io/UdpListener.scala +++ b/akka-actor/src/main/scala/akka/io/UdpListener.scala @@ -6,11 +6,12 @@ package akka.io import java.net.InetSocketAddress import java.nio.ByteBuffer import java.nio.channels.SelectionKey._ + import scala.annotation.tailrec import scala.util.control.NonFatal -import akka.actor.{ ActorLogging, Actor, ActorRef } +import akka.actor.{ Actor, ActorLogging, ActorRef } import akka.dispatch.{ RequiresMessageQueue, UnboundedMessageQueueSemantics } -import akka.util.ByteString +import akka.util.{ ByteString, Helpers } import akka.io.Inet.DatagramChannelCreator import akka.io.SelectionHandler._ import akka.io.Udp._ @@ -74,6 +75,7 @@ private[io] class UdpListener(val udp: UdpExt, log.debug("Unbinding endpoint [{}]", bind.localAddress) try { channel.close() + if (Helpers.isWindows) registration.enableInterest(OP_READ) sender() ! Unbound log.debug("Unbound endpoint [{}], stopping listener", bind.localAddress) } finally context.stop(self)