Python网络编程零基础2

版权声明:转载请声明 https://blog.csdn.net/dirckes8813/article/details/84887758

因为基础内容较多所以内容回顾较多(代码放到下面)

  1. 网络性能衡量指标

    • 带宽:通信信道上支持的最高数据传输频率
    • 速率:每秒中传输多少bits数据
    • 吞吞量:单位时间内通过某个网络数据量
    • 时延:传输时延,传播时延,处理时延,排队时延
  2. 常用概念

    • 服务器:提供服务的一方
    • 客户端:请求服务的一方
    • 通信:数据传输过程
    • 协议:数据组织、编码、传输、校验、解码规则
  3. 通信过程的几个问题

    • DNS:域名系统,获得对方IP地址
      域名 ====> IP地址
    • 联系上对方:客户端主动发起连接
    • 通信过程的正确性:协议来保证
    • 如何正确理解对方的意思:协议来保证
    • 关闭连接
  4. OSI/ISO七层参考模型

    • 应用层:提供用户服务,负责具体功能的实现
    • 表示层:数据格式的压缩,优化,加密
    • 会话层:建立应用的连接,选择合适的传输服务
    • *传输层:提供传输服务(程序之间)
    • 网路层:主机到主机间的数据传输
      路由,分段
    • 链路层:进行数据交换,控制具体收发
      相邻主机之间的通信
    • 物理层:定义机械、物理、电信标准
  5. TCP/IP四层模型

    • 应用层(应用层、表示层、会话层)
    • 传输层(传输层)
    • 网络层(网络层)
    • 物理链路层(数据链路层、物理层)
      • 将第一次分为两层,就是五层模型
  6. IP地址:网络上唯一的地址

    • 组成:32bits

    • 表示方式:点分十进制的表示方式
      将每8bits分成一组,使用十进制的数字表示
      11111111 11111111 11111111 11111111
      255.255.255.255

    • 特殊IP
      127.0.0.1 本机IP地址
      0.0.0.0 本机上绑定的所有IP地址
      网络地址 主机地址全部为0
      192.168.1.5
      192.168.1.0
      广播地址 主机地址部分全部为1
      192.168.1.5
      192.168.1.255

    • 私有地址:预留的一部分地址段,内网使用
      A类:10.0.0.1–10.255.255.254
      B类:172.16.0.1–172.31.255.254
      C类:192.168.0.1–192.168.255.254

  7. 端口号(端口地址):标识不同的服务
    组成:16bits整数
    范围:1~65535
    系统保留:1~1023 系统保留端口

  8. 传输层:进程到进程的数据传输

    • TCP:传输控制协议
      特点:面向连接,可靠传输,流量控制
      适用:数据量大,可靠性要求较高的通信
      传输效率较低

    • UDP:用户报文协议
      特点:无连接,不可靠传输
      适用:数据量小,可靠性要求不高
      传输效率较高

  9. 建立、释放连接过程

    • 建立:三次握手

      • 客户端发起连接请求,带上自己的序列号N
      • 服务器接收连接,产生应答
        N+1:期望收到你下一个包的序号N+1
        K:我自己的序列号K
      • 客户端发送确认
        K+1:期望收到你下一个包的序号是K+1
    • 释放:四次挥手

      • 主动方发起断开请求
      • 被动方应答,表示准备断开
      • 被动方发出消息,表示可以断开
      • 主动方发出指令,确认断开
  10. 服务器、客户端工作流程

    • 服务器:
      创建套接字->绑定->监听->接收->数据传输->关闭

    • 客户端:
      创建套接字->连接->数据传输->关闭

  11. 网络套接字(socket)

    • 什么是套接字
      用于计算机网络通信的一种接口

    • 套接字的类型

      • 流式套接字(SOCK_STREAM)
        可靠性传输、面向连接、数据无差错发送
        数据是一个字节流

      • 数据报套接字
        不可靠、无连接的数据传输
        数据是一个一个独立的数据报,每次发送都是
        一个数据报

    • 常用方法
      socket() 创建套接字
      bind() 绑定地址
      listen() 监听
      accept() 接收连接
      send() 发送
      recv() 接收
      connect() 连接(只能用于客户端)
      close() 关闭

今天的内容:

1. 服务循环接收、客户端循环发送

将服务器的recv(), 客户端的send()放入循环中

2. 网络缓冲区

- 每个socket被创建后,都会分配两个缓冲区
  输入、输出缓冲区,分别用于数据收、发
- 当send函数调用时,先将数据写入缓冲区
  send函数就认为发送成功,并返回
  由TCP协议决定何时从缓冲区发送到对方
- 当调用recv函数接收时,从输入缓冲区读取数据
  而不是直接从网络读取
- 优点:提高读写效率,协调收发速度

3. 粘包

- 粘包:多个数据包的数据到达接收缓冲区
        后一个包的头接着上一个包尾
  例如:
    AAABBB (两个数据包)

- 什么时候需要处理粘包
	如果多个数据包数据不同的分组,需要处理
	属于同一个分组,不需要处理

- 如何处理:
	方式一:在数据包的头部、尾部增加特殊标记
	   读取数据的时候,读取两个笔记中间的部分
	{2H:AAA:}{2H:BBB:}
	
	方式二:在每个数据包头增加长度信息
	        根据长度决定读取多少个字节数据
	   例如:头部采用4个字节表示长度
	   0003AAA0004BBBB
	   0003:表示该包数据部分长度为3
	       读取3个字节:AAA
	   0004:表示该包数据部分长度为4
	       读取4个字节:BBBB

**4. UDP套接字 **

1)面向无连接、不可靠传输、传输效率较高、
   适用于数据量少、可靠性要求不高的数据传输

2)UDP工作流程
  - 服务器
	  创建套接字->绑定地址->收发数据->关闭
	   * 没有listen,accept过程
  
  - 客户端
	  创建套接字->发送、接收数据->关闭

3)UDP套接字的主要函数
  - 创建套接字
    sockfd = socket(AF_INET, SOCK_DGRAM)
    参数:AF_INET   协议族,通过IP、端口
	                地址进行通信
		  SOCK_DGRAM  套接字类型
		              表示用户报文套接字
  - 绑定(服务器端)
    sockfd.bind(address)
	参数:address   绑定地址,由IP、端口构成
  
  - 接收:recvfrom
    data, addr = recvfrom(buffersize)
	  参数:buffersize   每次最多接收的字节数
	  返回值:data   接收的内容
	          addr   消息发送者的地址

  - 发送:sendto
    n = sendto(data, addr)
	  参数:data   要发送的数据,bytes格式
	        addr   接收者地址
	  返回值:实际发送的字节数

5. TCP和UDP套接字的对比

TCP				UDP
字节流			数据报
会产生粘包		不会产生粘包
可靠传输		不可靠传输
需要listen		不需要
    accept
客户端connect	客户端不需要connect
recv,send		recvfrom,sendto

6. socket常用的属性方法

family属性:地址类型
    AF_INET:发送方、接收方通过IP、端口来标识
	        IPV4
	AF_UNIX:本地socket,发送方、接收方位于
	        同一台机器,地址为文件路径
	AF_INET6:IPV6地址类型

type:socket类型
      SOCK_STREAM: 流式socket
	  SOCK_DGRAM: 数据报socket

getpeername(): 获取连接端的地址信息
getsockname(): 获取套接字绑定的地址

fileno(): 获取套接字的文件描述符
  文件描述符:操作系统内核分配的一个非负整数
              每个文件描述符代表一个文件
			  当打开或新建一个文件
			  内核都会返回一个文件描述符
			  文件读写、网络socket数据收发、
			  外设操作都是通过文件描述符进行
   例如:
     - 标准输入:sys.stdin   0  默认键盘
	 - 标准输出:sys.stdout  1  默认屏幕

setsockopt(level, optname, value)
  功能:设置套接字的选项
        不同的套接字选项代表不同的功能
  参数:
     level: 设置选项的类型
	 optname: 选项类型中的子类型
	 value:为选项设定的值

7. 广播

  1)什么是广播
    - 单播:一点发送、一点接收
	- 多播:也称组播,一点发送,特定的多个点接收
	- 广播:一点发送,该网段内容所有的节点接收
	  广播地址:IP地址的主机地址部分全部为1
	    例如:192.168.1.3,转换成二进制
	二进制:11000000 10101000 00000001 00000011
            |------- 网络地址 -------| |-主机-|
	广播地址:把主机地址部分全部替换成1
	        11000000 10101000 00000001 11111111
			192.168.1.255

  2)Python中如何实现广播
     - socket既发送也接收广播的时候
	   首先设置SO_BROADCAST选项为1,来支持广播通信

   setsockopt(SOL_SOCKET, SO_BROADCAST, 1)
 - 发送广播,使用特殊地址broadcast
   而不是标准的IP地址和主机名


基于UDP会话Server代码示例

# UDP 服务端 Server

import socket,time
tiMe = time.asctime()[11:19]
# 创建socket连接
sk = socket.socket(type=socket.SOCK_DGRAM)
# 绑定
sk.bind(('127.0.0.1',9999))
print('当前UDP服务端准备就绪',tiMe)
# 发送消息循环体
while True:
    # 获取消息和地址
    msg,addr = sk.recvfrom(1024)
    print('当前基于UDP%s连接已经建立'%addr[0])
    #打印消息
    print('来自客户端',addr[0],'的连接:|       ',msg.decode('utf-8'),
        '       |接收时间:',tiMe)
    #发送消息
    data = input('输入要发送的UDP:')
    sk.sendto(data.encode(),addr)
    # 判断退出
    if not msg or not data:
        break
# 关闭连接
sk.close()

基于UDP会话Client代码示例

#UDP 客户端Client

import socket,time
tiMe = time.asctime()[11:19]
# 创建套接字
sk = socket.socket(type=socket.SOCK_DGRAM)
# 绑定IP
ip_port = ('127.0.0.1',9999)
print('当前UDP客户端准备就绪',tiMe)
# 发送消息循环体
while True:
    # 发送消息
    data = input('输入要发送的UDP:')
    if not data:
        sk.sendto(''.encode(),ip_port)
        break
    sk.sendto(data.encode(),ip_port)
    # 接收消息
    msg,addr = sk.recvfrom(1024)
    print('当前基于UDP%s连接已经建立'%addr[0])
    print('来自服务器',addr[0],'的回复:|       ',msg.decode('utf-8'),
                '        |接收时间:',tiMe)
    if not msg:
        break
# 关闭连接
sk.close()


猜你喜欢

转载自blog.csdn.net/dirckes8813/article/details/84887758
今日推荐