• 8.23_python_lx_day30


    一.TCP基本语法

    import socket

    (1)服务端

    <1>创建一个socket对象

    sk = socket.socket()

    <2>绑定对应的ip和端口号(让其他主机在网络中可以找得到)

    #127.0.0.1代表本地ip
    sk.bind( ("127.0.0.1",9001) )

    <3>开启监听

    sk.listen()

    <4>建立三次握手

    conn,addr = sk.accept()

    <5>处理收发数据的逻辑

    #recv 接收 send 发送
    res = conn.recv(1024) # 代表一次最多接收1024个字节
    print(res.decode('utf-8'))

    <6>四次挥手

    conn.close()

    <7>退还端口

    sk.close()

    (2)客户端

    <1>创建一个socket对象

    sk = socket.socket()

    <2>与服务器建立连接

    sk.connect(   ('127.0.0.1',9001)  )

    <3>发送数据(只能发送二进制的字节流)

    sk.send('需要发送的字符串'.encode('utf-8'))

    <4>关闭连接

    sk.close()

    二.TCP循环发送消息

    (1)服务端

    <1>创建一个socket对象

    sk = socket.socket()

    <2>绑定对应的ip和端口号(让其他主机在网络中可以找得到)

    #127.0.0.1代表本地ip
    sk.bind( ("127.0.0.1",9001) )

    <3>开启监听

    sk.listen()

    <5>处理收发数据的逻辑

    while True:
        #<4>三次握手
        conn,addr = sk.accept()
        while True:
            res = conn.recv(1024)
            print(res.decode())
            strvar = input("请输入服务端要给客户端发送的内容")
            conn.send(strvar.encode())
            if strvar.upper() == "Q":
                break

    <6>四次挥手

    conn.close()

    <7>退还端口

    sk.close()

    (2)客户端

    <1>.创建socket对象

    sk = socket.socket()

    <2>连接服务端

    sk.connect( ("127.0.0.1" , 9000) )

    <3>收发数据

    while True:
        strvar = input("请输入您要发送的内容:")
        sk.send(strvar.encode())
        res = sk.recv(1024)
        if res == b"q" or res == b"Q":
            break
        print(res.decode())

    <4>关闭连接

    sk.close()

    三.udp基本语法

    (1)服务端

    <1>创建udp对象

    sk = socket.socket(type=socket.SOCK_DGRAM)

    <2>绑定地址端口号

    sk.bind( ("127.0.0.1",9000) )

    <3>udp服务器,在一开始只能够接受数据

    msg,cli_addr = sk.recvfrom(1024)
    print(msg.decode())
    print(cli_addr)
    # 服务端给客户端发送数据
    msg = "发送的字符串"
    sk.sendto(msg.encode(),cli_addr)

    <4>关闭连接

    sk.close()

    (2)客户端

    <1>创建udp对象

    sk = socket.socket(type = socket.SOCK_DGRAM)

    <2>收发数据的逻辑

    # 发送数据
    msg = "你好,你是mm还是gg"
    # sendto( 消息,(ip,端口号) )
    sk.sendto( msg.encode() ,  ("127.0.0.1",9000)  )
    # 接受数据
    msg,server_addr = sk.recvfrom(1024)
    print(msg.decode())
    print(server_addr)

    <3>关闭连接

    sk.close()

    四.udp循环发消息

    (1)服务端

    <1>创建udp对象

    sk = socket.socket(type=socket.SOCK_DGRAM)

    <2>绑定地址端口号

    sk.bind( ("127.0.0.1",9000) )

    <3>udp服务器,在一开始只能够接受数据

    while True:
        # 接受消息
        msg,cli_addr = sk.recvfrom(1024)
        print(msg.decode())
        message = input("服务端给客户端发送的消息是?:")
        # 发送数据
        sk.sendto(message.encode() , cli_addr)

    <4>关闭连接

    sk.close()

    五.黏包

    • 黏包出现的两种情况:
      •     (1) 发送端发送数据太快
      •   (2) 接收端接收数据太慢

    (1)struct

    • pack :
    •   把任意长度数字转化成具有固定4个字节长度的字节流
    • unpack :
    •   把4个字节值恢复成原来的数字,返回最终的是元组
    import struct
    # pack
    # i => int 要转化的当前数据是整型
    # pack 的范围 -2147483648 ~ 2147483647 21个亿左右
    res = struct.pack("i",2100000000)
    print(res , len(res)) # len(res) => 4
    
    # unpack
    # i => 把对应的数据转换成int整型
    tup = struct.unpack("i",res)
    print(tup) # (2100000000,)
    print(tup[0]) #2100000000
    • 解决黏包场景:
    •   应用场景在实时通讯时,需要阅读此次发的消息是什么
    • 不需要解决黏包场景:
    •   下载或者上传文件的时候,最后要把包都结合在一起,黏包无所谓

    (2)使用struct解决黏包问题

    <1>服务端

    import socket
    import struct
    sk = socket.socket()
    sk.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
    sk.bind( ("127.0.0.1",9000) )
    sk.listen()
    conn,addr = sk.accept()
    # 处理收发数据的逻辑
    strvar = input("请输入你要发送的数据")
    msg = strvar.encode()
    length = len(msg)
    res = struct.pack("i",length)
    # 第一次发送的是字节长度
    conn.send(res)
    # 第二次发送真实的数据
    conn.send(msg)
    # 第三次发送真实的数据
    conn.send("世界真美好123".encode())
    conn.close()
    sk.close()

    <2>客户端

    import socketimport struct
    sk = socket.socket()
    sk.connect( ("127.0.0.1",9000) )
    # 处理收发数据的逻辑
    # 第一次接受的是字节长度
    n = sk.recv(4)
    tup = struct.unpack("i",n)
    n = tup[0]
    # 第二次接受真实的数据
    res = sk.recv(n)
    print(res.decode())
    # 第三次接受真实的数据
    res = sk.recv(1024)
    print(res.decode())
    sk.close()
  • 相关阅读:
    Python+Selenium练习(二十六)- 多窗口之间切换
    Python+Selenium练习(二十五)-执行JavaScript
    Python+Selenium练习(二十四)- 鼠标右键
    Python+Selenium练习(二十三)- 组合键-退格键删除文字
    Python+Selenium练习(二十二)-组合键-全选文字
    Python+Selenium练习(二十一)-获取页面元素大小
    Python+Selenium练习(二十)-验证控件是否被选中
    Python+Selenium练习(十九)-获取元素上面的文字
    Python+Selenium练习(十八)-断言页面标题
    Python+Selenium练习(十七)-自定义浏览窗口大小
  • 原文地址:https://www.cnblogs.com/Magicianlx/p/13551569.html
Copyright © 2020-2023  润新知