Python全栈开发:socket代码实例

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

  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()
    

      

  

 

posted @ 2017-03-03 08:51  倪兴国  阅读(205)  评论(0编辑  收藏  举报