网络

作者: 遇明不散 | 来源:发表于2019-03-02 15:59 被阅读0次

    网络体系结构标准

    OSI模型

    • 1、网络信息传输比较复杂需要很多功能协同。
    • 2、将功能分开,降低耦合度,让每个模块完成一定的功能。
    • 3、将这些模块按照一定的顺序进行组合,完成功能,条理清晰。
      按照规定功能、顺序排列的体系结构,即为OSI模型。

    七层模型

    • 应用层
      提供用户服务,例如处理应用程序、文件传输、数据管理等。
    • 表示层
      数据的转换和压缩、解压的加密等。
    • 会话层
      决定了进程间的连接建立,选择使用了什么样的传输协议。
    • 传输层
      建立网络连接,提供合适的连接传输服务,提供流量控制。
    • 网络层
      控制分组传输,进行路由选择,网络互联。
    • 链路层
      提供链路交换,具体的数据收发。
    • 物理层
      物理硬件,具体的传输条件和传输接口。

    四层

    • 应用层(应用层、表示层、会话层)
    • 传输层
    • 网路层
    • 物理链路层(链路层、物理层)

    五层(TCP/IP模型)

    • 应用层(应用层、表示层、会话层)
    • 传输层
    • 网路层
    • 链路层
    • 物理层

    网络协议

    在网络传输过程中,为了保证通信的正常而制定的都遵守的约定。

    应用层协议

    TFTP、DNS、FTP、SMTP、HTTP

    传输层协议

    TCP、UDP

    网络层协议

    IP、ARP、ICMP

    物理链路层协议

    IEEE

    主机

    主机名称

    计算机名、域名,仅限于本地,用不了互联网。

    本地主机表示方法:IP

    表示本机在网络上的定位。

    • localhost127.0.0.1:表示本机通信地址。只有本机的其他程序可以访问,网络访问不了,也可叫本机回环地址,可用于本地模拟测试。
    • IP地址:表示本机在网络上的标识,可用于网络。0.0.0.0:表示在局域网内的可用主机IP,如果不知道本机的IP,可用0.0.0.0表示给本主机分配一个局域网内随机可用IP。

    相关函数

    // 导入相关模块
    import scoket                 
     
    // 获取主机名称
    socket.gethostname()   
             
    // 通过主机名称解析本机或主机服务器IP
    socket.gethostbyname('hostname') 
    
    //  解析本机localhost回环IP  
    socket.gethostbyname('localhost')   
                  
    /* 
    * 查看主机的信息,返回一个元组
    * 第一个参数表示主机名
    * 第二个参数表示主机别名
    * 第三个参数表示主机地址 
    * args可以是IP或域名  
    */
    socket.gethostbyaddr('args')
    

    IP地址

    指一台计算机在互联网中的标志

    IPv4

    表示方法
    • 点分十进制
      三个点将IP分为四个部分,每部分取值0~255
      例如:192.168.1.5,192.121.10.23,172.23.5.6 ...
    • 二进制
      32位二进制表示

    IPv6

    • 随着网络的发展,IPv4地址不够用了,为了扩展地址空间,研究出了IPv6。
    • IPv6为128位,用十六进制表示,两个十六进制占一组,大大扩展了地址空间。
    • 在我国,大部分的民用地址还是IPv4,有些商用地址是IPv6。

    192.168.1.0 表示该网段
    192.168.1.1 该网段的网关地址
    192.16.1.255 广播地址

    ping命令

    查看是否可以访问某台主机

    IP地址的转换

    /*
       socket.pton()与socket.ntop()有第一个参数
       AF_INET表示转化IPv4类地址
       AF_INET6表示转化IPv6类地址
      其余和socket.inet_aton()与socket.inet_ntoa()功能相同
    */
    
    // 将点分十进制转换为二进制
    socket.inet_aton('192.168.12.23')  // b'\xc0\xa8\x0c\x17'
    socket.inet_pton(socket.AF_INET,'192.168.12.23')  // b'\xc0\xa8\x0c\x17'
    
    // 将二进制转换为点分十进制
    socket.inet_ntoa(b'\xc0\xa8\x0c\x17')  // 192.168.12.23
    socket.inet_ntop(socket.AF_INET,b'\xc0\xa8\x0c\x17')   // 192.168.12.23
    

    域名

    互联网服务器IP的名字,方便使用

    端口号

    地址的组成部分,用于在一个系统中区分应用层程序
    取值范围:1~65536
    1 ~ 255 众所周知的端口,一些特有的程序会占用这些端口
    256 ~ 1023 系统程序占用的端口
    1024 ~ 49151 登记端口(可以使用)
    49152 ~ 65535 私有端口或者动态端口
    推荐使用10000以上的端口号

    获取系统中某个网络服务程序的端口号
    // 获取系统中某个网络服务程序的端口号
    socket.getservbyname('ssh')    // 22
    socket.getservbyname('mysql')  // 3306
    socket.getservbyname('http')   // 80
    

    子网掩码

    与IP配合使用,来确定当前的网段。
    按位相与即可得到当前网段。

    字节序

    • 小端序:低序字节存在低地址位
    • 大端序:高序字节存在低地址位
    • 网络统一:网络字节序,保证不同的主机按照相同方式发送接收解析数据

    TCP/UDP协议

    传输层提供的通信协议

    面向连接的可靠服务(TCP协议)
    • TCP协议规定:
      • 传输服务必须建立连接
      • 传输结束必须断开连接
      • 传输数据必须保证可靠
    • 建立连接(三次握手)
      • 客户端向服务端发送连接请求(发送一个试探性的标志字符给服务器)
      • 服务器端接收到请求后告知客户端可以连接
      • 再次告知服务器客户端已经收到回复,下面开始发送具体的消息
    • 数据的可靠性
      • 无重复
      • 无丢失
      • 无失序
      • 无错误
    • 断开连接(四次挥手)
      • 主动方送标志告知被动方要断开来连接
      • 被动方返回相应的标志信息告知主动方已经收到断开请求
      • 被动方会再次发送标志位信息表示已经准备就绪可以断开
      • 主动方断开连接告知被动方
    • 适用情况
      • 对传输质量要求较高,需要可靠的传输。
      • 传输的数据量较大,不需要频繁的连接断开
        比如:QQ消息、邮件收发、文件上传、账户登陆等
    面向无连接的不可靠服务(UDP协议)
    • 特点
      • 不保证数据的完整性
      • 数据的发送都是由发起端决定的,不考虑接收端的情况
      • 没有三次握手和四次挥手的过程
    • 适用情况
      • 对实时性要求较高
      • 网络情况不佳的时候
      • 对数据的准确性没有严格要求
      • 建立必要的非连接的情况(比如:广播组播)

    套接字

    网络间进行通信的方式的名称。
    在linux中演化为一种文件类型。

    套接字的分类

    流式套接字

    表示传输层使用TCP协议提供面向连接的传输服务,以字节流形式进行传输

    数据报套接字

    表示传输层使用UDP协议提供面向无连接的传输服务,以消息结构体形式进行传输

    原始套接字

    一般用于底层测试(一般用不到)

    基于TCP协议的socket编程

    服务端

    • 创建一个TCP流式套接字
      socket(family = AF_INET,type = SOCK_STREAM,proto = 0)

      • 功能:创建一个套接字
      • 参数:
        • family 协议族类型 (AF_INET、UNIX)
        • type 套接字类型
          SOCK_STREAM TCP流式套接字
          SOCT_DGRAM UDP数据报套接字
          SOCK_RAM 原始套接字
        • proto 自协议类型 一般为0
      • 返回值:套接字对象
    • 绑定本机的IP和端口号
      bind(address)

      • 功能:邦定本机的IP和端口号
      • 参数:一个包含两个元素的元组,元组第一个元素是主机名,第二个是使用的端口号
    • 将套接字变为可监听套接字
      listen(n)

      • 功能:
        • 将套接字设置为监听套接字,让套接字可以去接受多个客户端的连接请求
        • 设置一个连接等待队列
      • 参数:是一个正整数 >=1
    • 套接字等待客户端请求
      accept()

      • 功能:阻塞等待客户端的连接
      • 参数:无
      • 返回值:
        • 第一个返回值为和客户端交互的新的套接字
        • 第二个返回值为连接进来的客户端的address
    • 消息的收发
      recv(buffer)

      • 功能:接受网络消息
      • 参数:正整数,表示一次接受从缓冲区中拿到的消息的字节数
      • 返回值:返回接收到的消息
      • 当接收的网络缓冲中没有内容时会阻塞
    • 当连接断开后,recv会结束阻塞返回一个空字串
      send(data)

      • 功能:发送网络消息
      • 参数:要发送的内容
      • 返回值:实际发送的字节数
      • python3中要求send的内容必须为bytes格式

      sendall(data)

      • 功能:发送网路消息
      • 参数:要发送的内容要求为bytes格式
      • 返回值:如果成功发送返回None,发送失败报异常
    • 关闭套接字

    客户端

    connect(address)

    • 功能:向服务器发起连接请求
    • 参数:address是一个元组,即为要连接的服务器的地址
    • 注意点:
      • 客户端要和服务器端的套接字类型相同
      • 客户端就是用创建的套接字和服务器交互
      • recvsend要与服务器配合,避免recv死阻塞

    TCP循环服务不能满足多个客户端同时发送请求的情况,它不允许多个单个客户端单独长期占有服务器资源

    TCP数据传输

    recv会不断取出接受缓冲区中的内容,如果一次没有拿完,那么下次回继续收取没拿完的消息

    TCP粘包
    • TCP粘包指的是发送方发送若干次数据的时候,因为是数据流的传输方式,导致数据粘连在一起,接受方一次将多次发送的数据一起接受,产生接受数据的粘连。
    • 粘包是TCP传输特有的现象,因为TCP传输没有消息边界。
    • 如果是发送连续的内容,比如文件等则粘包没有影响。如果是每次发送为单独需要处理的内容则要处理粘包。
    处理粘包现象
    • 将消息个格式化
    • 发送消息的同时发送一个消息长度标志
    • 让消息的发送延迟,使接受端每次都能够有时间接受一个消息
    #!/usr/bin/python3
    # argv.py
    import sys
    // 将命令行内容收集为一个列表,每一个元素是命令行中的一项
    print(sys.argv)
    
    // ./argv.py ab cd
    print(sys.argv)   // ['argv.py','a','b']
    

    基于UDP协议的socket编程

    服务端

    • 创建数据包套接字
    • 绑定本地IP和端口
    • 收发消息
    • 关闭套接字

    客户端

    • 创建数据包套接字
    • 收发消息
    • 关闭套接字

    相关函数

    recvfrom(BUFFERSIZE)

    • 功能:在UDP中接受消息
    • 参数:BUFFERSIZE表示一次最多可以接受多少自己的消息
    • 返回值:
      data 接受到的消息
      addr 表示从哪个客户端接收到的消息
    • 每次只能接受一个数据包,如果数据包的大小超过recvfrom的设置大小则会出现数据丢失

    sendto(data,addr)

    • 功能:向一个网络终端发送消息
    • 参数:
      data 要发送的消息(bytes)
      addr 发送对象的地址

    TCP于UDP的区别

    • TCP是有连接的,UDP是无连接的
    • TCP有三次握手四次挥手的过程,UDP没有
    • TCP是以数据流传输数据,会有粘包,UDP是数据报的形式没有粘包
    • TCP的连接需要消耗一定的资源,相比之下UDP资源消耗少
    • TCP保证数据的可靠性,UDP不保证
    • TCP需要listen,accept,connect,UDP不需要

    套接字属性

    sock = socket.socket()

    • sock.getpeername()
      用作服务器连接套接字,查看连接的客户端地址
    • sock.getsockname()
      获取套接字对应绑定的地址和端口
    • sock.type
      获取套接字的类型
    • sock.fileno()
      获取套接字的文件描述符号码。
      系统会给进程中每个IO操作对象分配一个>=0的正整数作为标号,我们称之为该IO操作的文件描述符。一个进程中所有IO的文件描述符不会重复。
    • sock.setsockopt(level,optname,value)
      功能:设置套接字选项,可以增加或改变套接字的功能
      参数:
      level 要定义的选项类型
      optname 每种类型都有具体的选项,根据具体的需求选择选项进行设置
      value 将选择的选项设置为什么值
    • getsockopt(level,optname)
      功能:获取相应选项的值
      参数:
      level 要获取的选项类型
      optname 每种类型都有具体的选项,根据具体的需求选择要获取的选项
      返回值:获取到的值

    相关文章

      网友评论

          本文标题:网络

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