zoukankan      html  css  js  c++  java
  • Python网络编程(OSI模型、网络协议、TCP)

    前言:

    什么是网络?

    网络是由节点和连线构成,表示诸多对象及其相互联系。

    在数学上,网络是一种图,一般认为专指加权图。

    网络除了数学定义外,还有具体的物理含义,即网络是从某种相同类 型的实际问题中抽象出来的模型

    在计算机领域中,网络是信息传输、接收、共享的虚拟平台,通过它把各个点、面、体的信息联系到一起,从而实现这些资源的共享

    网络是人类发展史来最重要的发明,提高了科技和人类社会的发展。

    在1999年之前,人们一般认为网络的结构都是随机的。但随着Barabasi和Watts在1999年分别发现了网络的无标度和小世界特性并分别在世界著名的《科学》和《自然》           杂志上 发表了他们的发现之后,人们才认识到网络的复杂性。

    网络会借助文字阅读、图片查看、影音播放、下载传输、游戏、聊天等软件工具从文字、图片、声音、视频等方面给人们带来极其丰富的生活和美好的享受。

     
     
     
     
    网络目的:
          网络传输的目的是什么?
    •          没错就是:数据传输
     
      由于网络的复杂性以及各种应用硬件等等不匹配原因 
      和编码是一个道理你有你的我有我的会导致冲突等问题
      所以出现了 :ISO(国际标准化组织)
      ISO是干嘛的呢?
    •      他是一个非盈利性国际组织 这个组织制定了一个用于计算机或通讯系统间的互联网标准体系
    •      叫OSI模型  不仅包括一系列抽象的术语或概念,也包括具体的协议
    •      OSI公有七层 :
     
    1.     应用层: 提供用户服务,具体的内容由特定的程序规定
    2.     表示层: 提供数据的加密和压缩优化
    3.     会话层: 确定建立应用链接,选择传输服务
    4.     传输层: 提供数据传输服务,进行流量控制
    5.     网络层: 路由选着,网络互联
    6.     链路层: 提供链路交换,具体消息的发送
    7.     物理层: 物理硬件,接口,网卡的规定
     
    四层模型:
    1.     应用层 :  应用层   表示层  会话层
    2.     传输层 :  传输层
    3.     网络层 :  网络层
    4.     物理链路层: 链路层和物理层
     
    五层模型(tcp/ip模型):
    1.     应用层 : 应用层   表示层  会话层
    2.     传输层 : 传输层
    3.     网络层 : 网络层
    4.     链路层 : 链路层
    5.     物理层 : 物理层
     
     
    OSI模型优点
    •              将功能分开 降低网络中的耦合度,
    •              使用开发流程更加清晰,每部分各司其职
     
    高内聚低耦合:
    1.   高内聚:每个模块功能尽量单一,不会多个功能掺杂
    2.   低耦合:尽量降低每个模块之间的关联性
     
     
     
     
    网络协议:
    •           在网络通讯中协议必须遵守的规定,
    •           如建立什么连接,消息结构如何解析等
    • 应用层:TFTP(文件传输)、HTTP(超文本传输协议)、DNS(域名解析)、SMTP(邮件传输)
    • 传输层:TCP、UDP
    • 网络层:IP
    • 物理层:IEEE
     
    iPython3:socket模块
     
    网络相关概念:
        网络主机:在网络上确定一台主机
    1.         本地使用:127.0.0.1 或 “localhost”
    2.         网络地址:“0.0.0.0” 或 “172.168.40.53”
    •     ifconfig:查看本机IP (ens33:本地IP  lo:本地回还)
    •     ipconfig:windoes中
    •     socket.gethostname() :                      获取本机主机名
    •     socket.gethostbyname('tedu') :        利用主机名获取ip
    •     socket.gethostbyname('localhost'):   获取本地ip
     
    常用IP地址:
    1. IPv4: 点分十进制   例如:192.168.1.3   取值0~255(32位)
    2. IPv6: 128位
     
    网络连接测试
        ping 172.18.32.47
     
    特殊ip
    1.     127.0.0.1            本地IP测试
    2.     0.0.0.0                自动使用本地可用网卡IP
    3.     192.168.1.0        代表网段
    4.     192.168.1.1        通常为网关地址
    5.     192.168.1.255    广播地址
     
     
    访问主机IP地址:
        socket.gethostbyaddr('127.0.0.1')
        ('localhost', [], ['127.0.0.1'])
             主机     别名      ip地址
     
    IP十六进制转换:
    •     socket.inet_aton('192.168.1.2')
    •     b'xc0xa8x01x02'
    •     socket.inet_ntoa(b'xc0xa8x012')
    •      '192.168.1.2'
     
    域名:
    •     是指网络服务器地址在网络上的名称
    端口号:
    • 端口号是地址的一部分,在一个系统中每个网络(区分应用ip
    • 应用监听不同的端口,以获取对应的端口传递信息
    • 取值范围:1---------65535
    •                  1---------255   一些通用端口(众所周知的程序占用)
    •                  256------1023  系统端口
    •                 1024-----65535 自用端口
     
    获取应用程序的端口:
    1.     socket.getservbyname('ssh')
    2.     22
    1.     socket.getservbyname('mysql')
    2.     3306
     
     
    传输层服务:
     
     面向连接的传输服务(tcp协议):
    •         传输特征:
    •                可靠的数据传输:
    •                       可靠性:无失序、无差错、无重复、无丢失
    •                       在数据传输前和传输后需要建立连接和断开链接
    •        面向传输服务建立连接的过程:‘三次握手
    1. 客户端向服务器发送链接请求
    2. 服务器接受到请求进行确认,返回确认报文
    3. 客户端收到服务器回复最终确认链接
    •           面向传输服务断开链接的过程:‘四次挥手’
    1. 主动方发送报文,告知被动方要断开链接
    2. 被动方回复报文,表示已经接受到请求,准备断开
    3. 被动方再次发送报文,表示准备处理就绪,可以断开
    4. 主动方发送确认报文,断开链接
    •         应用情况:
    •     适用于传输较大的内容或文件,网络良好,
    •     需要保证传输可靠性的情况
    •     e.g.  信息聊天,文件上传下载,邮件,网页获取
     面向无连接的传输服务(udp协议):
    1. 不保证传输的可靠性
    2. 没有建立连接和断开的过程
    3. 数据的收发比较自由
    • 适用情况: 
    •     网络情况较差,对可靠性要求不高,收发消息的两端
    •     e.g.:网络视频,群聊,广播等
     
     
     
     
    socket 套接字编程:
        目的:
    • 通过编程语言提供的套接字编程接口
    •           可以更简单的完成基于tcp/udp的编程
        套接字:
    • 是完成上述目标的一种编程手段
        套接字类别:
          1.流式套接字(SOCK_STREAM):
    •          传输层基于套接字的协议通信
    •          面向连接可靠的传输  tcp的传输   流式套接字
          2.数据报套接字(SOCK_DGRAM):
    •          面向无连接不可靠的传输 udp的传输  数据报套接字
          3.低层套接字(SOCK_RAM):
    • 访问底层协议套接字
     
    TCP服务端:
       import socket
       1.创建套接字(函数):
          socket.socket(sock_family = AF_INET,
                  sock_type = SOCK_STREAM,
          proto = 0)
          功能:
    • 创建套接字
          参数:
    •  sock_family地址族类型   AF_INET:IPV4网络通讯
    •  sock_tpye:套接字类型   SICK_STREAM :流式   SOCK_DGRAM:数据报
    •  proto:通常为0  选定子协议类型
    •  返回值:返回一个套接字对象
       2.绑定地址(函数):
          sockfd.bind(addr)
            功能:
    • 绑定地址
            参数:
    • addr--->元组  (ip, port) ("0.0.0.0", 8888)
       3.设置监听套接字:
          sockfd.listen(n)
            功能:
    • 将套接字设置为监听套接字,创建监听队列
    参数:
    • 监听队列大小
    • 一个监听套接字可以连接多个客户端
       4.等待接受客户端链接:
          connfd,addr = sockfd.accept()  阻塞状态
          功能:
    • 阻塞等待并处理客户端链接
          返回值:
    1.            connfd:新的套接字,用于和客户端通讯
    2.            addr:链接客户端的地址(ip, port)
          阻塞函数
    •     当程序运行到阻塞函数位置,如果某种条件
    •     没有达成则暂停程序运行,直到条件达成结束阻塞
    -
       5.消息的收发:
          data = connfd.recvbuffersize
            功能:
    • 接受消息
            参数:
    •        一次接受消息的大小 字节
    •         返回值:返回接受的内容
          n = connfd.send(data)
            功能:
    • 发送消息
            参数:
    • 要发送的内容(bytes格式)
    •         返回值:返回实际发送的字节数
       6.关闭套接字
          sockfd.close()
     
    客户端:
        1.创建套接字 (和服务端套接字类型相同)
        2.发起链接
           connect(addr)
              功能:
    • 向服务端发起链接
      参数:
    • 服务器地址  (元组
        3.消息收发
        4.关闭套接字
     
    示例
    服务端:
     
    from socket import *
    
    # 创建套接字对象
    sockd = socket()
    # 绑定IP地址
    sockd.bind(("127.0.0.1", 6666))
    # 设置监听套接字
    sockd.listen(5)
    # 等待客户端链接
    cond, addr = sockd.accept()
    # 接受客户端消息(单次1024字节)
    data = cond.recv(1024)
    print(data.decode())
    # 发送消息
    cond.send(b"Hello, I'm the server")
    # 关闭套接字
    cond.close()
    sockd.close()

    这里本机测试可以利用两个进行 telnet命令链接服务端测试

     
     
    服务器:
    from socket import *
    
    # 创建套接字
    sockfd = socket(AF_INET, SOCK_STREAM)
    # 绑定地址
    sockfd.bind(("0.0.0.0", 8888))
    # 设置监听
    sockfd.listen(5)
    # 等待客户端链接
    print("waiting for connect....")
    conn, addr = sockfd.accept()
    print("Connect from", addr)
    print("Connect from", conn)
    
    # 消息收发
    while True:
        data = conn.recv(1024)
        if data.decode() == "":
            n = conn.send(b"Bey")
            break
        print("Receive", data.decode())
        n = conn.send(b"Receive your message")
        print("send %d" % n)
    # 关闭套接字
    conn.close()
    sockfd.close()

    客户端:

    # tcp_client.py
    
    from socket import *
    
    sockfd = socket()
    sockfd.connect(("172.18.32.31", 8888))
    while True:
        msg = input("Msg>>")
        if msg == "":
            break
        sockfd.send(msg.encode())
        data = sockfd.recv(1024)
        # if msg == "Bye":
        #     break
        print(data.decode())
    sockfd.close()
    简单的消息传输:

  • 相关阅读:
    Alpha冲刺总结
    测试随笔
    项目Alpha冲刺Day11
    项目Alpha冲刺Day12
    项目Alpha冲刺Day10
    项目Alpha冲刺Day9
    项目Alpha冲刺Day6
    beta冲刺1
    Beta准备博客
    基于微信小程序的实验室管理的postmortem
  • 原文地址:https://www.cnblogs.com/ParisGabriel/p/9434378.html
Copyright © 2011-2022 走看看