zoukankan      html  css  js  c++  java
  • Python网络练习题

    练习题

    1. 什么是C/S架构?

        
      C/S架构客户端、服务端架构,C/S端软件主要有网络游戏,QQ等
    2. 互联网协议是什么?分别介绍五层协议中每一层的功能?

        互联网协议:计算机之间的通信标准
      物理层:主要是基于电器特性发送高低电压(电信号),高电压对应数字1,低电压对应数字0。原始比特流在物理介质上的传输。
      数据链路层:定义电信号的分组方式,两台主机通过MAC地址进行通信。
      网络层:引入IP地址区分不同的广播/子网,选择正确的路由找到目标主机。
      传输层:建立端口到端口的通信,TCP,UDP。
      应用层:供操作系统或应用进行网络通信的标准接口(FTP,HTTP,TELNET)
    3. 基于tcp协议通信,为何建立链接需要三次握手,而断开链接却需要四次挥手

        因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,"你发的FIN报文我收到了"。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四次挥手.
    4. 为何基于tcp协议的通信比基于udp协议的通信更可靠?

        TCP协议的通信是面向连接的协议,只要不得到确认,就重新发送数据报,直到得到对方的确认为止。
      UDP协议的通信它是面向非连接的协议,它不与对方建立连接,而是直接就把数据包发送过去。
    5. ‍流式协议指的是什么协议,数据报协议指的是什么协议?

        
      流式协议指TCP
      数据报协议指UDP
    6. 什么是socket?简述基于tcp协议的套接字通信流程

        
      socket是应用层与TCP/IP协议通信的中间软件抽象层,它是一组接口。它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。
      所以,我们无需深入理解tcp/udp协议,socket已经为我们封装好了,我们只需要遵循socket的规定去编程,写出的程序自然就是遵循tcp/udp标准的。
    7. 什么是粘包? socket 中造成粘包的原因是什么? 哪些情况会发生粘包现象?

        TCP协议是面向流的协议,客户端把多个数据包合并在一起发送到服务端,就产生了粘包。
      由于接收方不知道消息之间的界限,不知道一次性提取多少字节的数据所造成的。
      只有TCP有粘包现象,UDP永远不会粘包

      客户端粘包:
      发送端需要等缓冲区满才发送出去,造成粘包(发送数据时间间隔很短,数据量很小,TCP优化算法会当做一个包发出去,产生粘包)

      服务端粘包:
      接收方不及时接收缓冲区的包,造成多个包接收(客户端发送了一段数据,服务端只收了一小部分,服务端下次再收的时候还是从缓冲区拿上次遗留的数据,产生粘包) 
    8. 基于socket开发一个聊天程序,实现两端互相发送和接收消息
    server.py
    
    
    import socket
    
    IP_PORT = ('127.0.0.1', 9999)
    sock_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock_server.bind(IP_PORT)
    
    sock_server.listen(5)
    print("start ……")
    while True:
        conn, addr = sock_server.accept()  # 阻塞直到有连接为止
        print('connect by ', addr)
        while True:
            try:
                data = conn.recv(1024)  # 收到数据
                if not data:
                    break
                print('server 收到的数据 ', data.decode())
                response = input(" input server msg >>> ").strip()
                conn.send(response.encode())
                print("send to data:", response)
    
            except ConnectionResetError:  # 适用于windows操作系统,防止客户端断开连接后死循环
                break
        conn.close()
    
    sock_server.close()
    
    -----------------------------------------------------------------------
    client.py
    
    import socket
    
    client_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    IP_PORT = ('127.0.0.1', 9999)
    client_sock.connect(IP_PORT)
    
    while True:
        msg = input(" input client msg >>> ").strip()
        if not msg:
            continue
        client_sock.send(msg.encode())  # 发送用户输入的数据,必须是bytes模式
        recv_data = client_sock.recv(1024)
        print('client recvive data ', recv_data.decode())  # 收到服务器的响应后
    

      

    9. 基于tcp socket,开发简单的远程命令执行程序,允许用户执行命令,并返回结果

    server:
      
    import socket
    import subprocess
    import struct
    import json
    
    def cmd_exec(cmd):
        """
        执行shell命令
        :param cmd:
        :return:
        """
        p = subprocess.Popen(cmd, shell=True,
                             stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    
        stdout, stderr = p.communicate()
        if p.returncode != 0:
            return stderr
        return stdout
    
    
    IP_PORT = ('127.0.0.1', 9999)
    sock_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock_server.bind(IP_PORT)
    
    sock_server.listen(5)
    print("start ……")
    while True:
        conn, addr = sock_server.accept()  # 阻塞直到有连接为止
        print('connect by ', addr)
        while True:
            try:
                data = conn.recv(1024)  # 收到数据
                if not data:
                    break
                print('客户端的命令', data.decode('GBK'))
                res = cmd_exec(data.decode('GBK'))  # 执行cmd命令
                # 构造消息头,命令+结果长度,防止粘包
                header = {
                    'cmd': data.decode('GBK'),
                    'res_size': len(res)
                }
                header_json = json.dumps(header)
                header_bytes = header_json.encode('utf-8')
    
                header = struct.pack('i', len(header_bytes))
                #  第二步:把报头长度发送给客户端
                conn.send(header)
                #  第三步:把报头内容发送给客户端
                conn.send(header_bytes)
    
                # 第四步:再发送真实的数据
                conn.sendall(res)
    
            except ConnectionResetError:  # 适用于windows操作系统,防止客户端断开连接后死循环
                break
        conn.close()
    
    sock_server.close()
    
    
    --------------------------------------
    
    client:
      
    import socket
    import struct
    import json
    
    client_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    IP_PORT = ('127.0.0.1', 9999)
    client_sock.connect(IP_PORT)
    
    while True:
        msg = input(" input client msg >>> ").strip()
        if not msg:
            continue
        client_sock.send(msg.encode('GBK'))  # 发送数据
    
        # 第一步:先收报头
        header = client_sock.recv(4)
        # 第二步:从报头中解析(header数据的长度)
        header_size = struct.unpack('i', header)[0]
        print('收到报头长度=', header_size)
        # 第三步:收到报头解析出对真实数据的描述信息
        header_json = client_sock.recv(header_size)
        header_dict = json.loads(header_json)
        print('收到报头内容=', header_dict)
        total_size = header_dict['res_size']
    
        # 第三步:接收真实的数据
        recv_size = 0
        recv_data = b''
    
        while recv_size < total_size:
            data = client_sock.recv(1024)
            recv_data += data
            recv_size += len(data)
    
            print('接收数据 =', recv_data.decode('gbk', 'ignore'))  # 如果设置为ignore,则会忽略非法字符;
    
    client_sock.close()
    

      

    10. 基于tcp协议编写简单FTP程序,实现上传、下载文件功能,并解决粘包问题

    11. 基于udp协议编写程序,实现功能

        1. 执行指定的命令,让客户端可以查看服务端的时间

        2. 执行指定的命令,让客户端可以与服务的的时间同步

    server:
    
    from socket import *
    import time
    import struct
    import json
    
    
    server = socket(AF_INET, SOCK_DGRAM)
    server.bind(('127.0.0.1', 8880))
    
    while True:
        print("waiting for message ……")
        # 收到报头长度
        action_type, client = server.recvfrom(1024)
        print('recv {}'.format(action_type.decode()))
        if not action_type:
            print('connect is lost ……')
            break
        if action_type:
            print('start sent to server time ……')
            server_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())
            time.sleep(1)
            server.sendto(server_time.encode('utf-8'), client)
    
    server.close()
    
    --------------------------------------------------------
    client:
    
    from socket import *
    import time
    import json
    import struct
    
    
    def send_msg(client, action_type, **kwargs):
        """
         打包消息,发送到服务器
        :param action_type:
        :param kwargs:
        :return:
        """
    
        # 发送cmd
        print('发送auth报头内容:{}'.format(action_type))
        client.sendto(action_type.encode("utf-8"), ('127.0.0.1',8880))
    
    
    if __name__ == '__main__':
    
        client = socket(AF_INET, SOCK_DGRAM)
    
        while True:
            cmd = input("input cmd >> ").strip()
            if not cmd: continue
            send_msg(client, cmd)
            data, server = client.recvfrom(1024)
            if cmd =='gettime':
                print("server time is", data.decode())
                print("local clock is", time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()))
            elif cmd == 'synctime':
                print("server time is {} start sync client clock ……".format(data.decode()))
                print("local clock is", data.decode())
            elif cmd == 'bye':
                break
            else:
                print('input cmd error')
        client.close()
    

      

  • 相关阅读:
    LOJ#3157. 「NOI2019」机器人 DP+拉格朗日插值
    BZOJ4832 [Lydsy2017年4月月赛]抵制克苏恩 记忆化搜索
    LazySysAdmin 靶机渗透
    zico2靶机渗透
    6_面向对象-下之关键字:static
    5_面向对象-中之单元测试方法、包装类的使用
    5_面向对象-中之Object类的使用
    5_面向对象-中之面向对象的特征三:多态性
    5_面向对象-中之子类对象实例化全过程
    5_面向对象-中之关键字:super
  • 原文地址:https://www.cnblogs.com/xiao-apple36/p/9356357.html
Copyright © 2011-2022 走看看