• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

03Python网络编程系列之服务端

python 搞java代码 3年前 (2022-05-21) 11次浏览 已收录 0个评论
# 这里边是一个定义了服务端的一系列函数,是Python网络<a href="https://www.gaodaima.com/tag/%e7%bc%96%e7%a8%8b" title="查看更多关于编程的文章" target="_blank">编程</a>这本书第七章的第一个例子。<br># 这是供后边函数进行调用了,然后我们来进行研究网络的单线程编程,多线程编程、异步网络编程等。<br><br># 导入网络编程socket、时间time、cmd参数获取模块<br>import argparse, socket, time<br><br># 定义一个字典用来存放发送给客户端的消息。<br>aphorisms = {b"Beautiful is <a href="https://www.gaodaima.com/tag/better" title="查看更多关于better的文章" target="_blank">better</a> <a href="https://www.gaodaima.com/tag/than" title="查看更多关于than的文章" target="_blank">than</a>?": b"Ugly.",<br>             b"Explicit is better than?": b"Implicit.",<br>             b"Simple is better than?": b"Complex."}<br><br># 获取答案, 如果客户端发送了问题,就从上边的字典里边获取,如果没有的话就返回我不知道的错误。<br>def get_answer(aphorism):<br>    """Return the string response to a particular Zen-of-Python aphorism."""<br>    time.sleep(0.0)  # increase to simulate an expensive operation<br>    return aphorisms.get(aphorism, b"Error: unknown aphorism.")<br><br># 定义一个函数用来获取终端需要传入的参数。 host:主机IP或者名称 -p:端口,默认为1060<br># 返回值是一个元祖,包含IP端口。<br>def parse_command_line(description):<br>    """Parse command line and return a socket address."""<br>    parser = argparse.ArgumentParser(description=description)<br>    parser.add_argument("host", help="IP or hostname")<br>    parser.add_argument("-p", metavar="port", type=int, default=1060,<br>                        help="TCP port (default 1060)")<br>    args = parser.parse_args()<br>    address = (args.host, args.p)<br>    return address<br><br># 创造一个socket套接字,这里的入参是上边那个函数的出参。<br>def create_srv_socket(address):<br>    """Build and return a listening server socket."""<br>    # 创造一个套接字。<br>    listener = socket.socket(socket.AF_INET, socket.SOCK_STREAM)<br>    # 设置。<br>    listener.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)<br>    # 服务端绑定IP和端口。<br>    listener.bind(address)<br>    # 设置服务端能够监听的数量,这里设置的是最大能够同时监听64个。<br>    listener.listen(64)<br>    # 打印出绑定的IP端口,服务端绑定的。<br>    print("Listening at {}".format(address))<br>    # 返回这个套接字。<br>    return listener<br><br># 一直持续不断的进行监听, 观察有没有客户端和服务端进行连接。<br># 这里的入参是上边函数的出参<br>def accept_connections_forever(listener):<br>    """Forever answer incoming connections on a listening socket."""<br>    # 死循环<br>    while True:<br>        # 服务端一直在监听端口,看有没有客户端进行连接。<br>        # 这个是阻塞的,如果有的话那么才会进行下边的操作。<br>        sock, address = listener.accept()<br>        # 打印出客户端IP端口<br>        print("Accepted connection from {}".format(address))<br>        handle_conversation(sock, address)<br><br># 处理连接对话函数。<br>def handle_conversation(sock, address):<br>    """Converse with a client over `sock` until they are done talking."""<br>    try:<br>        while True:<br>            # 这里一直处理客户端的请求。<br>            handle_request(sock)<br>    # 接收异常,代表着客户端断开了连接。<br>    except EOFError:<br>        print("Client socket to {} has closed".format(address))<br>    # 如果有其他错误,我们也需要进行接收下来。<br>    except Exception as e:<br>        print("Client {} error: {}".format(address, e))<br>    # 最后关闭服务端的套接字。<br>    finally:<br>        sock.close()<br><br># 处理请求函数。<br>def handle_request(sock):<br>    """Receive a single client request on `sock` and send the answer."""<br>    # 这里我们调用函数进行接收客户端发送过来的消息。<br>    aphorism = recv_until(sock, b"?")<br>    # 然后调用获取答案函数,将我们的答案回复给客户端。<br>    answer = get_answer(aphorism)<br>    # 服务端进行发送消息<br>    sock.sendall(answer)<br><br># 服务端和客户端进行连接后,一直进行接收客户端发送过来的消息,直到客户端发送了suffix<br># 这里我们的入参为?,如果客户端发送了suffix就代表着客户端发送完了消息。就需要进行关闭了。<br>def recv_until(sock, suffix):<br>    """Receive bytes over socket `sock` until we receive the `suffix`."""<br>    # 接收数据,<br>    message = sock.recv(4096)<br>    # 如果数据为空。就抛出一个连接关闭的错误。<br>    if not message:<br>        raise EOFError("socket closed")<br>    # 判断接收的消息最后是否是suffix,如果是地话,那我们就直接反悔了。<br>    # 如果不是,就代表着客户端还有数据进行发送,服务端就需要继续进行接收。<br>    while not message.endswith(suffix):<br>        # 能够进来while循环,就代表着客户端还有数据进行发送,<br>        # 那么我们需要继续进行接收<br>        data = sock.recv(4096)<br>        # 如果客户端的数据为空。<br>        # 再次抛出一个异常。<br>        if not data:<br>            raise IOError("received {!r} then socket closed".format(message))<br>        message += data<br>    # 返回接收的数据。<br>    return message

www#gaodaima.com来源gao!%daima.com搞$代*!码$网搞代码


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:03Python网络编程系列之服务端
喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址