美文网首页python学习实践生活不易 我用python
Python核心编程习题之二——网络编程

Python核心编程习题之二——网络编程

作者: 小奚有话说 | 来源:发表于2017-06-25 18:56 被阅读94次

    1. 面向连接的套接字和无连接的套接字之间的区别是什么?

    • 套接字是计算机网络数据结构,套接字最初是为同一主机上的应用程序所创建,使得主机上的不同应用程序可以相互通信,这就是所谓的进程间通信(Inter Process Communication,IPC)
    面向连接的套接字 无连接的套接字
    在通信之前必须建立连接 在通信之前不需要建立连接
    序列化的,可靠的不重复的数据交付 无法保证顺序性,可靠性或重复性,减少以一定的开销
    没有记录边界 保存了记录边界
    每条信息可以拆分成多个片段,并且每一个消息片段都能确保到达目的地,然后将他么按顺序组合在一起。 消息是以整体发送的。
    传输控制协议(TCP) 用户数据协议(UDP)

    2. 客户端/服务器架构

    • 服务器就是一系列硬件或软件,为一个或多个客户端(服务的用户)提供所需的“服务”。其存在的目的就是等待客户端的请求,并响应他们(提供服务),然后等待更多的请求。

    3. TCP和UDP之中,哪种类型的服务器接收连接,并将他们转换到独立的套接字进行客户端通信

    TCP
    

    4. 更新TCP(tsTclnt.py)和UDP(tsUclnt.py)客户端,以使得服务器名称无须硬编码到应用程序中。

    if __name__ == '__main__':
        opts, args = getopt.getopt(sys.argv[1:],'',['host=','port='])
        for op, value in opts:
            if op == '--host':
                HOST = value
            elif op == '--port':
                PORT = value
    

    在程序中加入这段代码,可以通过输入命令来进行指定的host和port

    5. 编写TCP客户端/服务器程序,使得服务器能够识别以下命令:

    • date 服务器返回当前日期/时间戳,即time.ctime()
    • os 获取操作系统信息(os.name)
    • ls 列出当前目录文件清单(提示:os.listdir()列出一个目录,os.curdir()是当前目录)
    tcp_server.py(服务器端代码)
    import socket
    from time import ctime
    import os
    import re
    
    HOST = ''
    PORT = 50006
    ADDR = (HOST, PORT)
    
    #获取指定路径的文件列表,默认为当前文件列表
    def list_dir(path = os.curdir):
        files = os.listdir(path)
        filenames = []
        for file in files:
            filenames.append(file)
        return '\n'.join(filenames)
    
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        s.bind(ADDR)
        s.listen(5)
        while True:
            conn, addr = s.accept()
            with conn:
                print('Connected by', addr)
                while True:
                    data = conn.recv(1024)
                    s_data = ''
                    if not data: break
                    data = data.decode('utf-8')
                    #判断指令为time
                    if data == 'time':
                        s_data = '[%s]'%ctime()
                    #判断指令为os
                    elif data == 'os':
                        s_data = '[%s]'%os.name
                    else:
                        #判断指令为ls
                        if data == 'ls':
                            s_data = list_dir()
                        else:
                            #判断指令为ls path
                            patt = 'ls\s([^\s]+)'
                            m = re.match(patt,data)
                            if m:
                                path = m.group(1)
                                if os.path.exists(path):
                                    s_data = list_dir(path)
                                else:
                                    s_data = 'not exist path'
                            else:
                                s_data = 'this is no order' + data
                    conn.send(s_data.encode('utf-8'))
    
    tcp_clnt.py(客户端代码)
    import socket
    
    HOST = 'localhost'
    PORT = 50006
    ADDR = (HOST, PORT)
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        s.connect(ADDR)
        while True:
            data = input('>>> ')
            if not data:break
            s.send(data.encode('utf-8'))
            data = s.recv(1024)
            if not data:break
            data = data.decode('utf-8')
            print(data)
    

    6. 半双工聊天

    hdserver.py(半双工聊天服务器)
    from socket import *
    
    HOST = ''
    PORT = 50006
    BUFSIZE = 1024
    ADDR = (HOST, PORT)
    
    with socket(AF_INET, SOCK_STREAM) as s:
        s.bind(ADDR)
        s.listen(5)
        while True:
            conn, addr = s.accept()
            with conn:
                print('connected by ',addr)
                while True:
                    data = conn.recv(BUFSIZE)
                    if not data:break
                    print('from:',data.decode('utf-8'))
                    data = input('to: ')
                    if not data:break
                    conn.send(data.encode('utf-8'))
    
    hdclnt.py(半双工聊天客户端)
    from socket import *
    
    HOST = 'localhost'
    POST = 50006
    BUFSIZE = 1024
    ADDR = (HOST, POST)
    
    with socket(AF_INET, SOCK_STREAM) as s:
        s.connect(ADDR)
        while True:
            data = input('to: ')
            if not data:break
            s.send(data.encode('utf-8'))
            data = s.recv(BUFSIZE)
            print('from: ',(data.decode('utf-8')))
    

    7. 全双工聊天

    fdserver.py(全双工服务器)
    from socket import *
    from select import *
    import sys
    
    HOST = ''
    PORT = 50007
    BUFSIZE = 1024
    ADDR = (HOST, PORT)
    
    with socket(AF_INET, SOCK_STREAM) as tcp_server:
        tcp_server.bind(ADDR)
        tcp_server.listen(5)
        inpu = [tcp_server, sys.stdin]
        while True:
            conn, addr = tcp_server.accept()
            inpu.append(conn)
            while True:
                r_list, w_list,e_list = select(inpu,[],[])
                for s in r_list:
                    if s == conn:
                        data = conn.recv(BUFSIZE)
                        if not data: break
                        print(data.decode('utf-8'))
                    else:
                        data = input('>>> ')
                        if not data: break
                        conn.send(data.encode('utf-8'))
    
    fdclnt.py(全双工聊天客户端)
    from socket import *
    from select import *
    import sys
    
    HOST = 'localhost'
    POST = 50007
    BUFSIZE = 1024
    ADDR = (HOST, POST)
    
    with socket(AF_INET, SOCK_STREAM) as tcp_clnt:
        tcp_clnt.connect(ADDR)
        inpu = [tcp_clnt,sys.stdin]
        while True:
            r_list, w_list, e_list = select(inpu,[],[])
            for s in r_list:
                if s == tcp_clnt:
                    data = tcp_clnt.recv(BUFSIZE)
                    if not data: break
                    print((data.decode('utf-8')))
                else:
                    data = input('>>> ')
                    if not data:break
                    tcp_clnt.send(data.encode('utf-8'))
    

    8. 多用户全双工聊天

    mfd_server(多用户全双工聊天服务器端)
    from socket import *
    import threading
    
    HOST = ''
    PORT = 21568
    BUFSIZE = 1024
    ADDR = (HOST, PORT)
    
    conns = []
    
    #当收到消息时,向其他用户发送消息
    def deal_conn(conn):
        while True:
            data = conn.recv(BUFSIZE)
            if not data:break
            for c in conns:
                if c != conn:
                    c.send(data)
    
    with socket(AF_INET, SOCK_STREAM) as server:
        server.bind(ADDR)
        server.listen(10)
        while True:
            conn, addr = server.accept()
            #向其他用户发送进入聊天室欢迎语
            if conn not in conns:
                for c in conns:
                    greet = '欢迎%s来到我们的聊天室!' %str(addr)
                    c.send(greet.encode('utf-8'))
                conns.append(conn)
            t = threading.Thread(target=deal_conn,args=(conn,))
            t.start()
    
    mfd_clnt.py(多用户全双工聊天客户端)
    from socket import *
    from select import *
    import sys
    
    HOST = 'localhost'
    POST = 21568
    BUFSIZE = 1024
    ADDR = (HOST, POST)
    
    with socket(AF_INET, SOCK_STREAM) as server:
        server.connect(ADDR)
        inpu = [server,sys.stdin]
        while True:
            r_list, w_list, e_list = select(inpu,[],[])
            for s in r_list:
                if s == server:
                    data = server.recv(BUFSIZE)
                    if not data: break
                    print((data.decode('utf-8')))
                else:
                    data = input('>>> ')
                    if not data:break
                    server.send(data.encode('utf-8'))
    

    9. 多用户、多房间、全双工聊天
    ####### mmfd_server(多用户多房间全双工聊天)

    from socket import *
    import re
    import threading
    
    HOST = ''
    PORT = 21568
    BUFSIZE = 1024
    ADDR = (HOST, PORT)
    
    rooms = {}
    conns = {}
    
    REFUSE = '对方正在聊天,您的请求拒绝连接'.encode('utf-8')
    WAITING = '请等待对方上线'.encode('utf-8')
    INPUT_ERROR = '您的输入有误'.encode('utf-8')
    
    
    def deal_conn(name):
        while True:
            conn_from = conns[name]
            data = conn_from.recv(BUFSIZE)
            if not data:break
            if rooms[name] in conns:
                conn_to = conns[rooms[name]]
                conn_to.send(data)
            else:
                conn_from.send(WAITING)
    
    with socket(AF_INET, SOCK_STREAM) as server:
        server.bind(ADDR)
        server.listen(10)
        while True:
            conn, addr = server.accept()
            settings = conn.recv(BUFSIZE)
            patt = r'name:(.+)\sto:(.+)'
            m = re.match(patt,settings.decode('utf-8'))
            if not m:conn.send(INPUT_ERROR)
            name = m.group(1)
            if name not in conns:
                conns[name] = conn
    
            to = m.group(2)
            if name not in rooms and to not in rooms:
                rooms[name] = to
                rooms[to] = name
            elif name in rooms and rooms[name] != to:
                del conns[name]
                if name in rooms:
                    del rooms[name]
                conn.send(REFUSE)
                conn.close()
    
            t = threading.Thread(target=deal_conn,args=(name,))
            t.start()
    
    mmfd_clnt(多用户多房间全双工聊天)
    from socket import *
    from select import *
    import sys
    
    HOST = 'localhost'
    POST = 21568
    BUFSIZE = 1024
    ADDR = (HOST, POST)
    
    with socket(AF_INET, SOCK_STREAM) as server:
        server.connect(ADDR)
        inpu = [server,sys.stdin]
        print("请输入你的姓名和对方的姓名(格式name:你的姓名 to:对方姓名)")
        data = input('')
        server.send(data.encode('utf-8'))
        while True:
            r_list, w_list, e_list = select(inpu,[],[])
            for s in r_list:
                if s == server:
                    data = server.recv(BUFSIZE)
                    if not data: break
                    print((data.decode('utf-8')))
                else:
                    data = input('>>> ')
                    if not data:break
                    server.send(data.encode('utf-8'))
    

    相关文章

      网友评论

        本文标题:Python核心编程习题之二——网络编程

        本文链接:https://www.haomeiwen.com/subject/dauvqxtx.html