python网络编程(三)

传输层编程

传输层

  • 网络层的任务是提供主机到主机的通信,而传输层的任务是提供进程到进程的通信
  • UDP(User Datagram Protocol)用户数据报协议
    • 采用无连接方式发送数据。
    • UDP面向无连接,不可靠,但因为不用传送许多于数据本身无关的信息,所以效率高。
  • TCP(Transmission Control Protocol)传输控制协议
    • 是一个可靠的、面向连接的协议。
    • 面向连接的TCP协议效率较低,但可靠性高,适合于网络链路不好或可靠性要求高的环境。
  • 进程与端口号
    • 在传输层中,使用端口(0~65535)来定义进程,端口号只具有本地意义。
  • 模型
    • 采用客户端-服务器端模式进行进程到进程的通信。
    • 运行在本地主机上的程序称为客户端,运行在远程主机上提供服务的程序称为服务器端。
    • 客户端的端口号通常随机选取,而服务器端的端口号一般是由IANA(互联网数字分配机构)指派的知名端口号。
    • 服务器端在知名端口上等待客户端的请求,客户端向服务器端上的知名端口发送服务请求,并得到响应。
  • 端口号的分配
    • 知名端口:0~1023,由IANA指派和控制。
      • 21/TCP FTP 文件传输协议
      • 22/TCP SSH 安全登录
      • 23/TCP Telnet 远程登录
      • 25/TCP SMTP 简单邮件传输协议
      • 80/TCP HTTP 超文本传输协议
      • 53/UDP DNS 域名解析
      • 69/UDP TFTP 简单文件传输协议
      • 161/UDP SNMP 简单网络管理协议
    • 注册端口:1024~49151,IANA不指派也不控制,但需要在IANA注册以防止重复。
    • 动态端口:49152~65535,不需要向IANA注册,可以由任何进程使用,也称短暂端口。

UDP

百度百科

  • UDP数据包

  • Python模拟UDP

    • UDP服务端udp_serber.py

      import socket
      
      
      """
      创建socket并指定socket的类型为UDP类型
      服务端在启动之后,会等待客户端的连接
      """
      with socket.socket(type=socket.SOCK_DGRAM) as server:
          # 绑定IP地址并设置端口号,127.0.0.1是网络回环地址,永远在线,用于测试当前主机是否在线
          server.bind(('127.0.0.1', 1000))
          print("成功访问UDP服务端!")
          # recvfrom该方法返回了客户端的地址与端口号,以及服务器端节接收到的数据
          # 1024代表服务器端接收的数据的长度
          data, address = server.recvfrom(1024)
          print(f"address : {address[0]}, port : {address[1]}, data : {data.decode()}")
          # 向客户端发送数据,address是客户端向服务器端发送数据时,所捕获的地址信息,包含IP地址
          server.sendto("访问成功!".encode(), address)
      
    • UDP客户端udp_client.py

      import socket
      
      
      with socket.socket(type=socket.SOCK_DGRAM) as client:
          send_data = "我是客户端"
          client.sendto(send_data.encode(), ('127.0.0.1', 1000))
          client_data, address = client.recvfrom(1024)
          print(f"收到的数据为:{client_data.decode()}")
      
    • 运行代码

      • 运行udp_serber.py

      • 打开CMD运行netstat -an可以看出1000端口已经启动。

      • 运行udp_client.py

      • 查看udp_server.py,客户端的端口是随机端口

  • Python实现聊天室功能

    server.py

    import socket
    
    """
    创建socket并指定socket的类型为UDP类型
    服务端在启动之后,会等待客户端的连接
    """
    with socket.socket(type=socket.SOCK_DGRAM) as server:
        # 绑定IP地址并设置端口号,127.0.0.1是网络回环地址,永远在线,用于测试当前主机是否在线
        server.bind(('127.0.0.1', 1000))
        # 设置自己的名字
        nickname = input("请输入你的名字:")
        print("服务端以连接,等待客户端连接")
        while True:
            # recvfrom该方法返回了客户端的地址与端口号,以及服务器端节接收到的数据
            # 1024代表服务器端接收的数据的长度
            data, address = server.recvfrom(1024)
            # 接收客户端的信息并打印
            print(data.decode())
            send_msginput("请输入要发送的信息:")
            if send_msg == 'quit':
                # 输入quit表示已下线
                server.sendto(f"{nickname}已下线".encode(), address)
                break
            # 向客户端发送数据,address是客户端向服务器端发送数据时,所捕获的地址信息,包含IP地址
            server.sendto(f"{nickname}:  {send_msg}".encode(), address)
    

    client.py

    import socket
    
    
    nickname = input("请输入你的名字:")
    with socket.socket(type=socket.SOCK_DGRAM) as client:
        while True:
            send_msg = input("请输入要发送的内容:")
            if send_msg == 'quit':
                client.sendto(f"{nickname}已下线".encode(), ('127.0.0.1', 1000))
                break
            client.sendto(f"{nickname}: {send_msg}".encode(), ('127.0.0.1', 1000))
            client_data, address = client.recvfrom(1024)
            print(client_data.decode())
    

    运行server.pyclient.py

TCP

百度百科

  • 格式

    • Source Port:16位的源端口号;包含初始化的通信端口,其中的源端口、源IP地址标示报文的返回地址。
    • Destination Port:16位的目的端口号;定义了传输的目的地,指明了应用程序的地址接口。
    • Sequence Number:32位的序列号;用于接收端,标示数据包,例如数据包的排序、拼接顺序。
    • Acknowledge Number:32位的确认序号;用于接收端,确认该数据包。
    • Offset:4位的数据偏移;TCP首部(包括选项)长度除以4。
    • Reserved:6位的保留位;必须为0,为了将来用于新的用途。
    • Flags:标志位;6种标志,详情见百度百科
    • Windows:表示接收缓冲区的空闲空间,16位,用来告诉TCP连接对端自己能够接收的最大数据长度,最大为65535。
    • Checksum:16位的校验和,证明数据的有效性。
    • Urgent Pointers:16位的紧急指针;只有URG标志位被设置时该字段才有意义,表示紧急数据相对序列号(Sequence Number字段的值)的偏移。
    • Options:选项。
    • data:上层协议的数据。
  • 三次握手

  • 四次挥手

  • Python 模拟TCP

    tcp_server.py

    import socket
    
    """
    创建服务器端的socket
    SOCK_STREAM代表TCP协议
    """
    with socket.socket(type=socket.SOCK_STREAM) as server:
        # 绑定IP地址和端口号
        server.bind(("127.0.0.1", 1000))  # 在bind中是传递的元祖
        print("TCP服务器已经启动")
        # 设置最大连接数,必须大于1
        server.listen(100)
        # 接收客户端的连接,当有客户端连接上来之后,会从服务端的socket里面创建出一个新的socket,新的socket用于服务于客户端
        client, address = server.accept()
        # address返回的是一个元祖
        print(f"当前的客户端的地址为:{address[0]},端口号为:{address[1]}")
        # 这里由于accept获取到了客户端的信息,因此接收数据使用了recv方法
        data = client.recv(1024)
        print(f"客户端发送的数据为:{data.decode()}")
        client.send("服务端收到消息".encode())
        # 关闭客户端的连接
        client.close()
    

    tcp_client.py

    import socket
    
    
    # 创建客户端的socket
    with socket.socket(type=socket.SOCK_STREAM) as client:
        # 哭护短连接服务器
        client.connect(("127.0.0.1", 1000))
        # 给服务端发送数据
        client.send("你好,我是客户端".encode())
        # 从服务端接收数据
        recv_data = client.recv(1024)
        # 打印服务端发送的数据
        print(f"服务端发送的数据为:{recv_data.decode()}")
    
  • 执行tcp_server.pytcp_client.py

posted @ 2022-06-07 18:06  行走的世界  阅读(49)  评论(0编辑  收藏  举报