def put(
    filename,
    output=None,
    interface=None,
    address=None,
    port=None,
    reporthook=None,
    timeout=None,
):
    """Send a file using the zget protocol.

    Parameters
    ----------
    filename : string
        The filename to be transferred
    output : string
        The alias to share on the network. Optional. If empty, the input
        filename will be used.
    interface : string
        The network interface to use. Optional.
    address : string
        The network address to use. Optional.
    port : int
        The network port to use. Optional.
    reporthook : callable
        A hook that will be called during transfer. Handy for watching the
        transfer. See :code:`urllib.urlretrieve` for callback parameters.
        Optional.
    timeout : int
        Seconds to wait until process is aborted. A running transfer is not
        aborted even when timeout was hit. Optional.

    Raises
    -------
    TimeoutException
        When a timeout occurred.

    """
    if port is None:
        port = utils.config().getint('DEFAULT', 'port')

    if interface is None:
        interface = utils.config().get('DEFAULT', 'interface')

    if not 0 <= port <= 65535:
        raise ValueError(_("Port %d exceeds allowed range") % port)

    basename = os.path.basename(filename)

    filehashes = []
    filehashes.append(hashlib.sha1(basename.encode('utf-8')).hexdigest())
    if output is not None:
        filehashes.append(hashlib.sha1(output.encode('utf-8')).hexdigest())

    if interface is None:
        interface = utils.default_interface()

    if address is None:
        address = utils.ip_addr(interface)

    server = StateHTTPServer((address, port), FileHandler)
    server.timeout = timeout
    server.filename = filename
    server.allowed_basenames.append(basename)
    if output is not None:
        server.allowed_basenames.append(output)
    server.reporthook = reporthook

    port = server.server_port

    utils.logger.debug(
        _("Using interface %s") % interface
    )

    utils.logger.debug(
        _("Listening on %(a)s:%(p)d \n"
          "you may change address using --address and "
          "port using --port") % {'a': address, 'p': port}
    )

    zeroconf = Zeroconf()

    infos = []
    for filehash in filehashes:
        utils.logger.debug(
            _("Broadcasting as %s._zget._http._tcp.local.") % filehash
        )
        infos.append(ServiceInfo(
            "_zget._http._tcp.local.",
            "%s._zget._http._tcp.local." % filehash,
            socket.inet_aton(address), port, 0, 0,
            {'path': None}
        ))

    try:
        for info in infos:
            zeroconf.register_service(info)
        server.handle_request()
    except KeyboardInterrupt:
        pass

    server.socket.close()
    for info in infos:
        zeroconf.unregister_service(info)
    zeroconf.close()

    if timeout is not None and not server.downloaded:
        raise utils.TimeoutException()
    else:
        utils.logger.info(_("Done."))
Send a file using the zget protocol.

    Parameters
    ----------
    filename : string
        The filename to be transferred
    output : string
        The alias to share on the network. Optional. If empty, the input
        filename will be used.
    interface : string
        The network interface to use. Optional.
    address : string
        The network address to use. Optional.
    port : int
        The network port to use. Optional.
    reporthook : callable
        A hook that will be called during transfer. Handy for watching the
        transfer. See :code:`urllib.urlretrieve` for callback parameters.
        Optional.
    timeout : int
        Seconds to wait until process is aborted. A running transfer is not
        aborted even when timeout was hit. Optional.

    Raises
    -------
    TimeoutException
        When a timeout occurred.

    
zget/put.py