zoukankan      html  css  js  c++  java
  • 网络编程 socket 开发练习题

    1 什么是C/S架构

    c指的是client(客户端软件),S指的是Server(服务端软件),C/S架构的软件,实现服务端软件与客户端软件基于网络通信

    2 互联网协议是什么?分别介绍五层协议中每一层的功能

    互联网协议就是计算机界的通讯标准

    物理层功能:主要是基于电器特性发送高低电压(电信号),高电压对应数字1,低电压对应数字0

    数据链路层的功能:定义了电信号的分组方式

    网络层功能:引入一套新的地址用来区分不同的广播域/子网,这套地址即网络地址

    传输层功能:建立端口到端口的通信 补充:端口范围0-65535,0-1023为系统占用端口

    应用层功能:将应用程序的数据打包传给传输层

    3 基于tcp协议通信,为何建立链接需要三次握手,而断开链接却需要四次挥手

    三次握手:client发送请求建立通道;server收到请求并同意,同时也发送请求建通道;client收到请求并同意,建立完成

    四次挥手:client发送请求断开通道;server收到请求并同意,但是这时sever可能还在发数据,并不关闭接口,所有回复同意和发送sever断开请求不是一同发送的;等到数据发送完毕server也发送请求断开通道;client受到消息结束

    4 为何基于tcp协议的通信比基于udp协议的通信更可靠?

    tcp协议是面向链接的协议,在通信过程中,双方通过三次握手建立连接、四次挥手断开连接,发送方给接收方发送数据,如果没有得到接收方的回应,就会继续给它发消息,直到接收方回应。

    udp是面向数据报的协议,不需要三次握手建立连接,它不会管接收方有没有收到数据

    5 ‍流式协议指的是什么协议,数据报协议指的是什么协议?

    流式协议指TCP协议,是通过三次握手建立连接再发送数据的,会存在粘包现象,当发送空消息时,对方并不会收到,不一定是一个send就要对应一个recv,传输效率低,网络开销大,可靠性高。

    数据报协议是指UDP协议,是以消息为单位发送的数据的,一个sendto就对应一个recvfrom,不会存在粘包现象,即使发送空消息也能收到,传输效率高,网络开销小,可靠性低。

    6 什么是socket?简述基于tcp协议的套接字通信流程

    socket是介于应用层和传输层之间的一组接口。将复杂的TCP/IP协议封装到接口里面,使用者只需要知道怎么用即可,不需要关心底层的实现。

    基于TCP的套接字通信流程:

    1)服务端:创建一个套接字对象;绑定本机地 址信息;开始时监听;接收连接;

    2)客户端:创建套接字对象;主动连接客户端;等待对方接收

    通过三次握手后建立连接,开始收发消息。

    收发消息完了之后,通过四次挥手断开连接。

    7 什么是粘包? socket 中造成粘包的原因是什么? 哪些情况会发生粘包现象?

    粘包是指两次命令执行的结果黏在一起。粘包发生在TCP协议中。

    造成粘包的原因:接收方不知道所要接收消息的大小和界限。

    发生粘包的情况:1、socket缓冲区导致,socket为了提高传输效率,往往会将较短时间间隔内较小的数据包合并发送,这样接收方就会收到一个粘包数据;

            2、接收方不知道该接收多大数据量,当接收方的最大接收量小于消息大小时,会发生粘包。

    8 基于socket开发一个聊天程序,实现两端互相发送和接收消息

    import socket
    
    sev = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sev.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    sev.bind(('127.0.0.1', 9999))
    sev.listen(5)
    print('starting...')
    while True:
        conn, client_addr = sev.accept()
        print(conn)
        print(client_addr)
        while True:
            try:
                data = conn.recv(1024)
                print(data.decode())
                inp = input('-->').strip()
                conn.send(inp.encode())
            except ConnectionResetError:
                break
    conn.close()
    sev.close()
    import socket
    
    cli = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    cli.connect(("127.0.0.1", 9999))
    while True:
        inp = input('---->').strip()
        if not inp:
            continue
        cli.send(inp.encode())
        data = cli.recv(1024)
        print(data.decode())
    cli.close()

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

    import socket
    import subprocess
    import json
    import struct
    
    sev = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sev.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    sev.bind(('127.0.0.1', 5555))
    sev.listen(5)
    print('start'.center(50, '-'))
    while True:
        conn, addr = sev.accept()
        while True:
            try:
                cmd = conn.recv(1024)
                obj = subprocess.Popen(cmd.decode(),
                                 shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
                stdout = obj.stdout.read()
                stderr = obj.stderr.read()
                total_size = len(stdout)+len(stderr)
                dict_msg = {'file_name': 'a.txt',
                            'md5': 12431564,
                            'total_size': total_size}
                dict_bytes = json.dumps(dict_msg).encode()
                header = struct.pack('i', len(dict_bytes))[0]
                conn.send(header)
                conn.send(dict_bytes)
                conn.send(stdout)
                conn.send(stderr)
            except ConnectionResetError:
                break
        conn.close()
    sev.close()
    import socket
    import struct
    import json
    
    cli = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    cli.connect(('127.0.0.1', 5555))
    while True:
        cmd = input('-->')
        if not cmd:
            continue
        cli.send(cmd.encode())
        obj = cli.recv(4)
        header_len = struct.unpack('i', obj)[0]
        header = cli.recv(header_len)
        dict_msg = json.loads(header.decode())
        total_size = dict_msg['total_size']
        recv_size = 0
        recv_data = b''
        while recv_size < total_size:
            data = cli.recv(1024)
            recv_size += len(data)
            recv_data += data
        print(recv_data.decode('gbk'))
    cli.close()

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

    import json
    import socket
    import os
    import struct
    BASE_DIR = os.path.dirname(os.path.abspath(__name__))
    SHARE_PATH = os.path.join(BASE_DIR, 'share')
    print(SHARE_PATH)
    class Sever():
        def __init__(self):
            print('start....')
            self.ser = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.ser.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
            self.ser.bind(('127.0.0.1', 9999))
            self.ser.listen(5)
            self.run()
    
        def run(self):
            while True:
                self.conn, self.client_addr = self.ser.accept()
                while True:
                    try:
                        cmd_b = self.conn.recv(1024)
                        cmd, file_name = cmd_b.decode().split()
                        if hasattr(self, cmd):
                            func = getattr(self, cmd)
                            func(file_name)
                        else:
                            print('none...')
    
                    except ConnectionResetError:
                        break
    
        def get(self, file_name):
            '''客户端下载'''
            if os.path.exists('%s\%s' % (SHARE_PATH, file_name)):
                file_size = os.path.getsize('%s\%s' % (SHARE_PATH, file_name))
                dict_msg = {'file_name': file_name,
                            'md5': 124521,
                            'file_size': file_size,
                            'file': True}
                header = json.dumps(dict_msg).encode()
                header_size = len(header)
                self.conn.send(struct.pack('i', header_size))
                self.conn.send(header)
                with open('%s\%s' % (SHARE_PATH, file_name), 'rb') as f:
                    for line in f:
                        self.conn.send(line)
                    else:
                        print('send has done...')
            else:
                dict_msg = {'file_name': file_name,
                            'md5': 124521,
                            'file_size': None,
                            'file': False}
                header = json.dumps(dict_msg).encode()
                header_size = len(header)
                self.conn.send(struct.pack('i', header_size))
                self.conn.send(header)
                print('file not exist')
    
        def put(self, file_name):
            '''客户端上传'''
            obj = self.conn.recv(4)
            header_len = struct.unpack('i', obj)[0]
            header = self.conn.recv(header_len)
            dict_msg = json.loads(header.decode())
            file_size = dict_msg['file_size']
            with open('%s\%s' % (SHARE_PATH, file_name), 'wb')as f:
                recv_size = 0
                while recv_size < file_size:
                    data = self.conn.recv(1024)
                    f.write(data)
                    recv_size += len(data)
                print("%s 接受完成" % file_name)
    
    
    sever = Sever()
    import socket
    import json
    import struct
    import os
    BASE_DIR = os.path.dirname(os.path.abspath(__name__))
    DOWMLOAD_PATH = os.path.join(BASE_DIR, 'download')
    
    class Client():
        def __init__(self):
            self.cli = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.cli.connect(("127.0.0.1", 9999))
            print('go....')
            while True:
                inp = input('-->').strip()
                if not inp:
                    continue
                try:
                    cmd, file_name = inp.split()
                except ValueError:
                    print('输入不合法')
                    continue
                self.cli.send(inp.encode())
                if hasattr(self, cmd):
                    func = getattr(self, cmd)
                    func(file_name)
    
        def get(self,file_name):
            obj = self.cli.recv(4)
            header_size = struct.unpack('i', obj)[0]
            header = self.cli.recv(header_size)
            dict_msg = json.loads(header.decode())
            if dict_msg['file']:
                file_size = dict_msg['file_size']
                recv_size = 0
                with open("%s\%s" % (DOWMLOAD_PATH, file_name), 'wb')as f:
                    while recv_size < file_size:
                        data = self.cli.recv(1024)
                        f.write(data)
                        recv_size += len(data)
                    print('%s 下载完成 ' % file_name)
            else:
                print('%s 不存在 ' % file_name)
    
    
    
        def put(self,file_name):
            if os.path.exists('%s\%s' % (DOWMLOAD_PATH, file_name)):
                file_size = os.path.getsize('%s\%s' % (DOWMLOAD_PATH, file_name))
                dict_msg = {'file_name': file_name,
                            'md5': 124521,
                            'file_size': file_size,
                            'file': True}
                header = json.dumps(dict_msg).encode()
                header_size = len(header)
                self.cli.send(struct.pack('i', header_size))
                self.cli.send(header)
                with open('%s\%s' % (DOWMLOAD_PATH, file_name), 'rb') as f:
                    for line in f:
                        self.cli.send(line)
                    else:
                        print('send has done...')
            else:
                print('file not exist')

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

    import socket
    
    sev = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sev.bind(('127.0.0.1', 9999))
    print('start...')
    while True:
        msg, client_addr = sev.recvfrom(1024)
        print(msg.decode())
        inp = input('-->').strip().encode()
        sev.sendto(inp, client_addr)
    import socket
    cli = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    
    while True:
        inp = input('-->').strip()
        cli.sendto(inp.encode(), ('127.0.0.1', 9999))
        msg, sever_addr =cli.recvfrom(1024)
        print(msg.decode())
  • 相关阅读:
    Cannot execute request on any known server
    swagger快速开发
    SpringBoot(七):SpringBoot整合Swagger2
    集群、分布式
    分布式架构--基本思想汇总
    Mysql联合查询union和union all的使用介绍
    Mysql 语句执行顺序
    Spring AOP四种实现方式Demo详解与相关知识探究
    jvm运行时环境属性一览
    使用ObjectOutputStream进行socket通信的时候出现固定读到四个字节乱码的问题
  • 原文地址:https://www.cnblogs.com/lys666/p/10047382.html
Copyright © 2011-2022 走看看