'Write a datagram.
@param addr: should be a tuple (ip, port), can be None in connected
mode.'

def write(self, datagram, addr=None):

    if self._connectedAddr:
        assert (addr in (None, self._connectedAddr))
        try:
            return self.socket.send(datagram)
        except socket.error as se:
            no = se.args[0]
            if (no == errno.WSAEINTR):
                return self.write(datagram)
            elif (no == errno.WSAEMSGSIZE):
                raise error.MessageLengthError('message    too    long')
            elif (no in (errno.WSAECONNREFUSED, errno.WSAECONNRESET, ERROR_CONNECTION_REFUSED, ERROR_PORT_UNREACHABLE)):
                self.protocol.connectionRefused()
            else:
                raise
    else:
        assert (addr != None)
        if ((not isIPAddress(addr[0])) and (not isIPv6Address(addr[0])) and (addr[0] != '<broadcast>')):
            raise error.InvalidAddressError(addr[0], 'write()    only    accepts    IP    addresses,    not    hostnames')
        if (isIPAddress(addr[0]) and (self.addressFamily == socket.AF_INET6)):
            raise error.InvalidAddressError(addr[0], 'IPv6    port    write()    called    with    IPv4    address')
        if (isIPv6Address(addr[0]) and (self.addressFamily == socket.AF_INET)):
            raise error.InvalidAddressError(addr[0], 'IPv4    port    write()    called    with    IPv6    address')
        try:
            return self.socket.sendto(datagram, addr)
        except socket.error as se:
            no = se.args[0]
            if (no == errno.WSAEINTR):
                return self.write(datagram, addr)
            elif (no == errno.WSAEMSGSIZE):
                raise error.MessageLengthError('message    too    long')
            elif (no in (errno.WSAECONNREFUSED, errno.WSAECONNRESET, ERROR_CONNECTION_REFUSED, ERROR_PORT_UNREACHABLE)):
                return
            else:
                raise
