zoukankan      html  css  js  c++  java
  • 网络基础

    端口:

      拥有IP地址的主机可以提供许多服务.比如Web服务,FTP服务,SMTP服务这些服务完全通过1个IP地址来实现.那么,主机是怎样区分不同的网络服务呢?显然不能只靠IP地址,因为IP地址与网络服务关系是一对多的关系.实际上是通过"IP地址+端口号"来区分不同的服务.

      端口是为了将同一台电脑上的不同程序进行隔离

      IP是找电脑,而端口是找电脑上的程序.

    示例:

      MySQL是一个软件,软件帮助我们在硬盘上进行文件操作.默认端口:3306

      Redis是一个软件,软件帮助我们在内存里进行数据操作.默认端口:6379

      网站默认端口:80  ,访问时 :http://www.luffycity.com:80

      网站默认端口:443 ,访问时:https://www.luffycity.com:443

    端口范围:

      1~65535   但是1~1024是内置(默认)不可用

    OSI 7层模型

      人们按照分工不同把互联网协议从逻辑上划分了层级:

      

    应用层 : 使用软件     打开软件或网站
    表示层 : 看到数据,图片,视频    生产数据:szwwd
    会话层 : 保持链接状态或登录     应用偷偷携带一点其他数据:令牌19rRNAwf8GVe6xyT9kJPIu5SlQc
    
    socket模块:
    传输层 : TCP/UDP      [TCP][szwwd|19rRNAwf8GVe6xyT9kJPIu5SlQc]
    网络层 : IP     【IP】【[TCP][szwwd|19rRNAwf8GVe6xyT9kJPIu5SlQc]】
    数据链路层 : MAC        [MAC][【IP】【[TCP][szwwd|19rRNAwf8GVe6xyT9kJPIu5SlQc]】]
    物理层 : 将数据转换成电信号发送
    TCP是因特网中的传输城协议,使用三次握手协议链接.当主动发出SYN请求链接后,等待对方回答SYN+ACK[1],并最终对对方的SYN执行ACK确认.这种建立连接的方法可以防止产生错误的连接.
    
    tcp三次握手过程:
    客户端发送SYN(SEQ = x)报文给服务端,进入SYN_SEND状态
    服务器端收到SYN报文,回应一个SYN(SEQ = y)ACK(ACK = x+1)报文,进入SYN_RECV状态.
    客户端收到服务器端的SYN报文,回应一个ACK(ACK = y+1)报文,进入Established状态.
    三次握手完成,TCP客户端和服务端成功建立连接,可以开始数据传输.
    TCP三次握手
    建立一个连接需要三次握手,而终止一个连接要经过四次握手,这是由TCP的半关闭(half-close)造成的。
    (1) 某个应用进程首先调用close,称该端执行“主动关闭”(active close)。该端的TCP于是发送一个FIN分节,表示数据发送完毕。
    (2) 接收到这个FIN的对端执行 “被动关闭”(passive close),这个FIN由TCP确认。
    注意:FIN的接收也作为一个文件结束符(end-of-file)传递给接收端应用进程,放在已排队等候该应用进程接收的任何其他数据之后,因为,FIN的接收意味着接收端应用进程在相应连接上再无额外数据可接收。
    (3) 一段时间后,接收到这个文件结束符的应用进程将调用close关闭它的套接字。这导致它的TCP也发送一个FIN。
    (4) 接收这个最终FIN的原发送端TCP(即执行主动关闭的那一端)确认这个FIN。[1] 
    既然每个方向都需要一个FIN和一个ACK,因此通常需要4个分节。
    注意:
    (1) “通常”是指,某些情况下,步骤1的FIN随数据一起发送,另外,步骤2和步骤3发送的分节都出自执行被动关闭那一端,有可能被合并成一个分节。[2] 
    (2) 在步骤2与步骤3之间,从执行被动关闭一端到执行主动关闭一端流动数据是可能的,这称为“半关闭”(half-close)。
    (3) 当一个Unix进程无论自愿地(调用exit或从main函数返回)还是非自愿地(收到一个终止本进程的信号)终止时,所有打开的描述符都被关闭,这也导致仍然打开的任何TCP连接上也发出一个FIN。
    无论是客户还是服务器,任何一端都可以执行主动关闭。通常情况是,客户执行主动关闭,但是某些协议,例如,HTTP/1.0却由服务器执行主动关闭。[2] 
    TCP四次挥手

    FTP进度条

    #模拟进度条原理
    import time
    
    def func(size,total_size):
        val = int(size/total_size*100)
        time.sleep(0.02)
        print("
    %s%%|%s"%(val,"*"*val),end="")
        
    for i in range(101)
        func(i,100)
    #os模块
    import os
    size = os.stat(r'D:sylars15day311.进度条.py').st_size
    print(size)
    计算文件大小

    文件上传

    import os
    import json
    import socketserver
    import shutil
    
    CODE = {'1001':'上传文件,从头开始上传'}
    
    def upload(cmd_dict,conn,username):
        """
        服务端完成上传文件(含断点续传)
        :param cmd_dict:
        :param conn:
        :return:
        """
        #2.获取文件信息
        file_md5 = cmd_dict['md5']
        file_name = cmd_dict['file_name']
    
        file_path_path = os.path.join('home',username,file_md5)
        file_name_path = os.path.join('home',username,file_name)
        
        #判断文件是否存在
        exist = os.path.exists(file_md5_path)
        if not exist:  #不续传
        #3.1.1 可以开始上传了
            response = {'code':1001}
            conn.sendall(json.dumps(response).encode('utf-8'))
    
        #3.1.2接收上传文件内容
            f = open(file_md5_path,'wb')
            recv_size = 0
            while recv_size < upload_file_size:
                data = conn.recv(1024)
                f.write(data)
                f.flush()
                recv_size+=len(data)
            f.close()
        #3.1.3改名字
            shutil.move(file_md5_path,file_name_path)
        else: #续传
            #3.2 续传+大小
            exist_size = os.stat(file_md5_path).st_size
            response = {'code':1002,'size':exist_size}
            conn.sendall(json.dumps(response).encode('utf-8'))
    
            f = open(file_md5_path,'ab')
            recv_size = reist_size
            while recv_size < upload_file_size:
                data = conn.recv(1024)
                f.write()
                f.fiush()
                recv_size += len(data)
            f.close()
    
            #3.2.1改名字
            shutil.move(file_md5_path,file_name_path)
    
    class NbServer(sockeretserver.BaseRequestHandler):
        def handle(self):
            """
            self.request 是客户端的socket对象
            :return:
            """
            #1.接收命令
            upload_cmd_bytes = self.request.recv(8096)
            cmd_dict = json.loads(upload_cmd_bytes.decode('utf8'))
    
            if cmd_dict['cmd'] == 'upload':
                upload(cmd_dict,self.request,'wj')
            elif cmd_dict['cmd'] == 'download':   #下载
                pass
    
    if __name__ =='__main__':
        server = socketserver,ThreadingTCPServer(('127.0.0.1',8001),NbServer)
        server.serve_forever()
    server
    import os
    import socket
    import json
    import hashlib
    
    CODE = {'1001':'上传文件,从头开始上传'}
    
    def file_md5(file_path):
        """
        文件进行md5加密
        :param file_path:
        :return:
        """
        obj = open(file_path,'rb')
        m = hashlib.md5()
        for line in obj:
            m.update(line)
        obj.close()
        return m.hexdigest()
    
    def jdt(size,total_size):
        """
        显示进度条
        :return:
        """
        val = int(size/total_size*100)
        print('
    %s%%|%s'%(val,"*"*val),end='')
    
    def send_file(exist_size,file_total_size):
        """
        发送文件
        :param exist_size:开始读取字节的位置
        :param file_total_size: 文件总字节大小
        :return:
        """
        f = open(file_path,'rb')
        f.seek(exist_size)
        send_size = exist_size
        while send_size < file_total_size:
            data = f.read(1024)
            sk.sendall(data)
            send_size += len(data)
            jdt(send_size,file_total_size)
        f.close()
        print("上传成功")
    
    def upload(file_path):
        """
        文件上传(含断点)
        :param file_path:
        :return:
        """
        file_md5_val = file_md5(file_path)
        file_name = os.path.basename(filee_path)
        file_size = os.stst(file_path).st_size
    
        cmd_dict = {'cmd':'upload','file_name':file_name,'size':file_size,'md5':file_md5_val}
        upload_cmd_bytes = json.dumps(cmd_dict).encode('utf-8')
        sk.sendall(upload_cmd_bytes)
    
        #2.等待服务端的响应
        response = json.loads(sk.recv(8096).decode('utf-8'))
        if response['code'] == 1001:
            send_file(0,file_size)
        else:
            #断点续传
            exist_size = response['size']
            send_file(exist_size,file_size)
    
    sk = socket.socket()
    sk.connect(('127.0.0.1',8001))
    
    while True:
        #upload|文件路径
        user_input = input("请输入要执行的命令:")
        #1.自定义协议{'cmd':'upload','file_path':'....'}
        cmd,file_path = user_input.split('|',maxsplit = 1)
        if cmd == 'upload':
            upload(file_path)
        elif cmd == 'download':
            pass
    client

      

  • 相关阅读:
    懒加载数据,在取出数据时容易出的bug....
    小程序申请及小程序发布
    SSL证书申请及安装
    iview modal 覆盖问题
    取消div独占一行的特性
    GPS坐标互转:WGS-84(GPS)、GCJ-02(Google地图)、BD-09(百度地图)、(百度坐标转谷歌坐标)
    工厂方法模式
    STS创建SpringBoot项目
    snmp协议学习记录
    操作系统命令学习记录
  • 原文地址:https://www.cnblogs.com/wangjun187197/p/9606686.html
Copyright © 2011-2022 走看看