Ticket #2699: udp-reconnect-disconnect.patch

File udp-reconnect-disconnect.patch, 4.0 KB (added by Martin Gergov, 9 years ago)

Reconnect and disconnect a udp socket

  • twisted/test/test_udp.py

     
    314314        """
    315315        A call to the transport's connect method fails with a L{ValueError}
    316316        when a non-IP address is passed as the host value.
    317 
    318         A call to a transport's connect method fails with a L{RuntimeError}
    319         when the transport is already connected.
    320317        """
    321318        client = GoodClient()
    322319        port = reactor.listenUDP(0, client, interface="127.0.0.1")
    323320        self.assertRaises(ValueError, client.transport.connect,
    324321                          "localhost", 80)
     322       
     323        return port.stopListening()
     324
     325    def test_disconnect(self):
     326        """
     327        A call to the transport's disconnect method before connecting raises
     328        a L{RuntimeError}, because we're not connected yet.
     329
     330        When connected to a remote server we can disconnect.
     331        Note: optional test(if extensions are built it will run).
     332        """
     333        client = GoodClient()
     334        port = reactor.listenUDP(0, client, interface="127.0.0.1")
     335        self.assertRaises(RuntimeError, client.transport.disconnect)
     336
    325337        client.transport.connect("127.0.0.1", 80)
    326         self.assertRaises(RuntimeError, client.transport.connect,
    327                           "127.0.0.1", 80)
     338        try:
     339            res = client.transport.disconnect()
     340        except NameError as e:
     341            if "disconnect" in e.message:
     342                port.stopListening()
     343                raise unittest.SkipTest("cannot test without "+\
     344                                            "disconnect extension")
     345            raise
     346        else:
     347            self.assertEqual(client.transport._connectedAddr, None)
     348            self.assertEqual(res, 0)
     349
    328350        return port.stopListening()
    329351
    330352
  • twisted/topfiles/setup.py

     
    3535    Extension("twisted.python.sendmsg",
    3636              sources=["twisted/python/sendmsg.c"],
    3737              condition=lambda _: sys.platform != "win32"),
     38
     39    Extension("twisted.python.disconnect",
     40              sources=["twisted/python/disconnect.c"],
     41              condition=lambda _: sys.platform != "win32"),
    3842]
    3943
    4044if sys.version_info[:2] <= (2, 6):
  • twisted/internet/udp.py

     
    2424import warnings
    2525
    2626from zope.interface import implementer
     27from twisted.python.runtime import platformType
    2728
    28 from twisted.python.runtime import platformType
     29#Try to import C extension, if not disconnect will not work
     30try:
     31    from twisted.python.disconnect import disconnect_udp_sock
     32except ImportError:
     33    pass
     34
    2935if platformType == 'win32':
    3036    from errno import WSAEWOULDBLOCK
    3137    from errno import WSAEINTR, WSAEMSGSIZE, WSAETIMEDOUT
     
    205211        """
    206212        'Connect' to remote server.
    207213        """
    208         if self._connectedAddr:
    209             raise RuntimeError("already connected, reconnecting is not currently supported")
    210214        if not abstract.isIPAddress(host):
    211215            raise ValueError("please pass only IP addresses, not domain names")
    212216        self._connectedAddr = (host, port)
    213217        self.socket.connect((host, port))
    214218
     219    def disconnect(self):
     220        """
     221        'Disconnect' from remote server.
     222        Not to be confused with loseConnection. It will NOT call connectionLost.
     223        @returns: the result from the underlying syscall.
     224        """
     225        if not self._connectedAddr:
     226            raise RuntimeError("not connected, connect the socket first")
     227        self._connectedAddr = None
     228        return disconnect_udp_sock(self.fileno())
     229
    215230    def _loseConnection(self):
    216231        self.stopReading()
    217232        if self.connected: # actually means if we are *listening*