• Python学习----网络编程


    网络:网络就是实现资源共享和信息传递的虚拟平台,我们可以编写基于网络通信的程序。比如socket编程,web开发

    Socket编程

    Socket是程序之间通信的一个工具,好比显示生活中的电话,你知道了对方的电话号码之后,需要使用电话进行通讯。同理你知道了对方的ip 地址和端口号之后,你需要使用socket进行通信。

    在通信之前,我们需要选择网络通讯协议(网络传输方式)。保证程序之间按照指定的规则进行数据通信

    TCP

    TCP 简称 传输控制协议,它是一种面向连接的、可靠的、基于字节流的传输层通信协议。
    1、面向连接:通信双方必须先建立好连接才能进行数据传输,并且双方都会为此连接分配必要资源用来记录连接的状态和信息。当数据传输完成之后,双方必须断开此连接,以释放系统资源。
    2、可靠传输:

    TCP采用发送应答机制:
    	通过TCP这种方式发送的每个报文段都必须得到接收方的应答才认为这个TCP报文段发送成功
    超时重传
    	发送端发送一个报文之后就会启动定时器,如果指定的时间内没有得到应答就会重新发送这个报文
    错误校验
    	TCP用一个 校验和 函数来校验数据是否有错误,在发送和接收时都要计算 校验和
    流量控制和阻塞管理
    	流量控制用来避免发送端发送过快而使得接收方来不及接收
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    通信步骤:
    1、创建连接
    2、传输数据
    3、关闭连接

    python编码转换

    在网络中传输的数据都是二进制的数据,所以我们在发送数据的时候需要将数据转换为二进制,到达目的地之后再将二进制数据转换回来。
    转码: encode
    解码: decode

    TCP客户端程序开发

    开发流程:
    在这里插入图片描述

    开发步骤:
    1、导入socket模块
    import socket
    2、创建客户端socket对象
    socket.socket(AddressFamily , Type)
    AddressFamily:IP地址类型,分为Ipv4和Ipv6
    type:传输协议类型
    3、建立连接
    connect
    4、数据传输
    send:发送数据
    recv:接收数据
    close:关闭连接
    代码演示:

    import socket
    
    if __name__ == '__main__':
        # 1、创建客户端套接字对象
        # 静态常量  AF_INET代表Ipv4  SOCK_STREAM代表TCP协议
        tcp_client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        # 2、和服务器建立套接字连接。参数是元组,指定ip和端口
        tcp_client_socket.connect(("127.0.0.1", 8888))
        # 3、发送数据,需要进行编码
        tcp_client_socket.send("hello".encode(encoding="utf-8"))
        # 4、接收数据,每次接收数据的大小,单位是字节,recv会阻塞等待数据到来,如果你不需要接收数据,那就跳过这步
        recv_data = tcp_client_socket.recv(1024)
        print(recv_data.decode())  # 默认utf-8解码,可省略不写
        # 5、关闭客户端套接字
        tcp_client_socket.close()
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    TCP服务端程序开发

    1、创建服务端套接字对象
    2、绑定IP地址和端口号,通过bind()函数完成
    3、设置监听 , listen()函数
    4、等待接收客户端连接请求
    5、接收数据
    6、发送数据
    7、关闭套接字

    开发步骤:
    1、导入socket模块
    import socket
    2、创建服务端socket对象
    socket.socket(AddressFamily , Type)
    AddressFamily:IP地址类型,分为Ipv4和Ipv6
    type:传输协议类型
    3、绑定ip地址和端口
    bind
    4、设置监听
    listen
    5、等待接收客户端的连接请求
    accept
    发送数据
    6、数据传输
    send:发送数据
    recv:接收数据
    close:关闭连接

    代码演示:

    import socket
    
    if __name__ == '__main__':
        # 1、创建服务端套接字
        tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    
    
        # 设置端口复用,关闭程序之后,电脑端口释放需要时间,但是实际上是已经释放了,
        # 但程序认为没有释放,所以关闭程序之后立即启动会报错
        # 直接进行强制复用
        tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
    
        # 2、绑定ip地址和端口号
        # tcp_server_socket.bind(("192.168.31.59", 8888))
        tcp_server_socket.bind(("", 8888))  # 不设置的话,会自动填充本机ip地址
        # 3、设置监听
        tcp_server_socket.listen(128)  # 参数128:代表服务端等待排队连接的最大数量,超出的限制的连接就丢弃
        # 4、等待客户端请求
        # 这步会阻塞等待,如果接收到请求,返回一个用以和客户端通讯的socket,和客户端地址
        # 上面创建的socket只是监听,不会发送数据
        connect_socket, ip_port = tcp_server_socket.accept()
        print("客户端地址:", ip_port)
        # 5、接收数据
        recv_data = connect_socket.recv(1024)
        print("接收到的数据:", recv_data.decode())
        # 6、发送数据
        connect_socket.send("客户端数据已收到".encode())
        # 7、关闭套接字
        connect_socket.close()
        tcp_server_socket.close()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    socket的发送和接收缓冲区

    当创建一个TCP socket对象的时候,会有一个发送缓冲区和一个接收缓冲区,这个发送和接收缓冲区就是内存中的一片空间。

    当你要发送消息时,先将消息存放在缓冲区,当消息达到一定的数量之后再一次性进行发送。

    send原理解析:
    问题:send是不是直接把数据发送给服务端?
    不是,要想发送数据,必须得通过网卡发送数据,应用程序无法直接通过网卡发送数据,它需要调用操作系统接口,也就是说,应用程序把发送得数据先写入到发送缓冲区(内存一片空间),再由操作系统控制网卡把发送缓冲区得数据发送给服务端网卡。

    recv原理解析:
    问题:recv是不是直接从客户端接收数据?
    不是,应用程序无法直接通过网卡接收数据,它需要调用操作系统接口,由操作系统通过网卡接收数据,把接收得数据写入接收缓冲区(内存一片空间),应用程序再从接收缓冲区获取客户端发送得数据。

    在这里插入图片描述

    Demo多任务版TCP服务端程序
    import socket
    import threading
    
    
    def tcp_server_thread(connect_socket, ip_port):
        print("客户端地址:", ip_port)
        # 5、接收数据
        recv_data = connect_socket.recv(1024)
        print("接收到的数据:", recv_data.decode())
        # 6、发送数据
        connect_socket.send("客户端数据已收到".encode())
        # 7、关闭套接字
        connect_socket.close()
    
    
    if __name__ == '__main__':
        # 1、创建服务端套接字
        tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    
        # 设置端口复用,关闭程序之后,电脑端口释放需要时间,但是实际上是已经释放了,但程序认为没有释放,所以关闭程序之后立即启动会报错
        # 直接进行强制复用
        tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
        # 2、绑定ip地址和端口号
        # tcp_server_socket.bind(("192.168.31.59", 8888))
        tcp_server_socket.bind(("", 8888))  # 不设置的话,会自动填充本机ip地址
        # 3、设置监听
        tcp_server_socket.listen(128)  # 参数128:代表服务端等待排队连接的最大数量,超出的限制的连接就丢弃
        while True:
            # 4、等待客户端请求
            # 这步会阻塞等待,如果接收到请求,返回一个用以和客户端通讯的socket,和客户端地址
            # 上面创建的socket只是监听,不会发送数据
            connect_socket, ip_port = tcp_server_socket.accept()
            server_thread = threading.Thread(target=tcp_server_thread, args=(connect_socket, ip_port))
            server_thread.start()
        tcp_server_socket.close()
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
  • 相关阅读:
    java基于微信小程序的大学生个人家庭理财产品 uniapp小程序
    基于MQTT的信息推送系统设计与实现
    使用idea运行VUE项目
    STM32F103 USART1 IDLE FLAG
    Java之HashMap和TreeMap
    【java爬虫】使用selenium获取某宝联盟淘口令
    【集合】ConcurrentHashMap数据结构?
    0815(031天 线程/进程02)
    数据结构 | 顺序表
    Java中加号的多种用途
  • 原文地址:https://blog.csdn.net/m0_48639280/article/details/128138384