Python全栈开发:socket代码实例

时间:2021-06-01 08:23:36

客户端与服务端交互的基本流程

  1. 服务端server
    #!/usr/bin/env python
    # -*- coding;utf-8 -*-
    import socket sk = socket.socket()
    sk.bind(("127.0.0.1", 9999))
    sk.listen(5)
    while True:
    conn, address = sk.accept()
    conn.sendall(bytes("欢迎访问老男孩!",encoding="utf-8"))
    while True:
    ret_bytes = conn.recv(1024)
    ret_str = str(ret_bytes, encoding="utf-8")
    print(ret_str)
    if ret_str == "q":
    break
    conn.sendall(bytes("答:" + "好!", encoding="utf-8"))
  2. 客户端client
    #!/usr/bin/env python
    # -*- coding;utf-8 -*-
    import socket obj = socket.socket()
    obj.connect(("127.0.0.1", 9999))
    ret_bytes = obj.recv(1024)
    ret_str = str(ret_bytes, encoding="utf-8")
    print(ret_str)
    while True:
    inp = input("请输入内容:\n 问:")
    obj.sendall(bytes(inp, encoding="utf-8"))
    if inp == 'q':
    break
    else:
    ret = str(obj.recv(1024), encoding="utf-8")
    print(ret)
    obj.close()

粘包问题解决方案:一个类型文件发送完毕之后进行一次确认信息交互。

  1. server(粘包)
    #!/usr/bin/env python
    # -*- coding;utf-8 -*- import socket sk = socket.socket()
    sk.bind(("192.168.1.107", 9999,)) # 传入元组
    sk.listen(5) # 监听客户端请求,最多有五个客户端请求等待)
    # 连接,客户端的地址信息(IP,port)
    while True:
    conn, address = sk.accept() # accept表示阻塞,等待连接请求
    conn.sendall(bytes("欢迎访问老男孩!", encoding="utf-8"))
    file_size = str(conn.recv(1024), encoding="utf-8")
    print(file_size)
    conn.sendall(bytes("开始吧!", encoding="utf-8"))
    total_size = int(file_size)
    has_recv = 0
    with open("c11.py", "wb") as f:
    i = 0
    while True:
    if total_size == has_recv:
    print("接收完毕!")
    break
    data = conn.recv(1024)
    f.write(data)
    has_recv += len(data)
    obj.close()
  2. client(粘包)
    #!/usr/bin/env python
    # -*- coding;utf-8 -*-
    import socket
    import os obj = socket.socket()
    obj.connect(("192.168.1.107", 9999))
    result_bytes = obj.recv(1024) # 等待发送消息
    result_str = str(result_bytes, encoding="utf-8")
    print(result_str)
    # 发送当前文件大小
    file_size = os.stat("client(粘包).py").st_size
    print("文件大小:" + str(file_size))
    obj.sendall(bytes(str(file_size), encoding="utf-8"))
    obj.recv(1024)
    with open("client(粘包).py", "rb") as f:
    seed_size = 0
    for i, line in enumerate(f, 1):
    obj.sendall(line)
    seed_size += len(line)
    if seed_size == file_size:
    print("发送完毕!")
    obj.close()

IO多路复用在socket中的运用:针对老用户和新用户,服务器做出不同的响应

  1. server服务端
    #!/usr/bin/env python
    # -*- coding;utf-8 -*-
    """
    IO多路复用socket实例代码
    """
    import socket
    import select sk1 = socket.socket()
    sk1.bind(("127.0.0.1", 8001))
    sk1.listen(5)
    inputs = [sk1, ]
    info_sender = []
    message = {} while True:
    # select自动监听文件描述符,发生变化则放入r_list列表中
    r_list, w_list, e_list = select.select(inputs, info_sender, [], 1)
    # print("正在监听的对象数量:%d" % len(inputs))
    for sk in r_list:
    # sk 表示每个连接对象
    if sk == sk1:
    # 有新用户建立连接
    conn, address = sk.accept()
    conn.sendall(bytes("hello", encoding="utf-8"))
    inputs.append(conn)
    message[conn] = []
    else:
    # 有老用户发送信息
    try:
    date = str(sk.recv(1024), encoding="utf-8")
    except Exception as e:
    e_list.append(sk)
    else:
    if sk not in info_sender:
    info_sender.append(sk)
    message[sk].append(date) for sk in w_list:
    re = message[sk][0]
    del message[sk][0]
    sk.sendall(bytes(re + "hello", encoding="utf-8"))
    # 给我发送信息的对象,我回复了信息就要把它排除,不然前面有while循环,和for循环,就会不断给对方回复消息!
    info_sender.remove(sk) for sk in e_list:
    inputs.remove(sk)
  2. 客户端client(client1,client2,client3):当用户第一次连接时执行相同的操作,支持多用户与服务器交互,客户端断开连接,服务器不受影响
    #!/usr/bin/env python
    # -*- coding;utf-8 -*-
    import socket sk1 = socket.socket()
    sk1.connect(("127.0.0.1", 8001))
    while True:
    content1 = str(sk1.recv(1024), encoding="utf-8")
    a = []
    print(content1)
    while True:
    inp = input(">>>")
    if inp == "q":
    a.append(inp)
    break
    else:
    sk1.sendall(bytes(inp, encoding="utf-8"))
    content2 = str(sk1.recv(1024), encoding="utf-8")
    print(content2)
    if a == ["q"]:
    break
    sk1.close()