python 网络编程 day01

2018.8.6

目录

网络编程

网络相关概念

IP地址

传输层服务

socket 套接字编程

TCP的服务端

TCP的客户端


day01

网络编程  3

进程线程  3.5

网络 + 进程线程 1.5

MongoDB 4

regex 1.5

项目编程 2.5

难点:IO多路复用

           项目编写

           多任务编程理解 

网络编程

网络目的:数据传输

ISO(国际化标准化组织)

OSI七层模型...》 网络通信的标准化流程

  1. 应用层:提供用户服务,具体的内容由特定的程序规定
  2. 表示层:提供数据的加密和压缩优化
  3. 会话层:确定建立应用连接,选择传输服务
  4. 传输层:提供数据传输服务,进行流量控制
  5. 网络层:路由选择,网络互联
  6. 链路层:提供链路交换,具体的消息发送
  7. 物理层:物理硬件,接口,网卡的规定

四层模型

  1. 应用层
  2. 传输层
  3. 网络层
  4. 物理链路层

五层模型(TCP/IP模型)

  1. 应用层(应用层  表示层  会话层)
  2. 传输层
  3. 网络层
  4. 链路层
  5. 物理层

OSI模型优点:将功能分开,降低网络传输中的耦合度,使开发流程更加清晰,每部分各司其职

高内聚:每个模块功能尽量单一,不会多个功能掺杂

低耦合:尽量降低每个模块之间的关联系

要求:能够顺序说出七层模型,五层模型,知道每一层干什么事情,理解消息传输流程

网络协议:在网络通信中协议各方必须遵守的规定,如建立什么连接,消息结构如何解析等

5层模型 对应的协议
应用层 TFTP HTTP DNS SMTP
传输层 TCP UDP
网络层 IP
物理层 IEEE

网络相关概念

网络主机:在网络上确定一台主机

  1. 网络主机:在网络上确定一台主机
  2. 本地使用:'localhost'  127.0.0.1
  3. 网络地址:'0.0.0.0'  '172.60.50.54' (本机网络IP)
  4. 查看本机IP地址:ifconfig    (linux)
                                ipconfig   (windows)
  5. ipython3   进入交互模式
  6. 通过计算机名获取匹配的IP
    In [5]: socket.gethostbyname('tedu')
    Out[5]: '127.0.1.1'

    In [6]: socket.gethostbyname('localhost')
    Out[6]: '127.0.0.1'

  7. 获取计算机名: 
    In [2]: socket.gethostname() 
    Out[2]: 'tedu'

IP地址

  1. 在网络上确定一台主机的地址

    1. IPv4 :点分十进制 比如 192.168.1.72  0–255 
      32位二级制表示

    2. IPv6 : 128位二进制

网络连接测试

  1. ping 172.60.50.60

特殊IP

特殊ip 表示意思
127.0.0.1 本地测试IP
0.0.0.0 使用局域网内可用的IP
192.168.1.0 表示当前网段
192.168.1.1 通常是网络节点设备的IP (网关)
192.168.1.255 广播地址

通过域名获取服务器信息

socket.gethostbyaddr('www.baidu.com')
('127.0.0.1', [],    ['119.75.213.61'])
   主机     主机别名   主机IP

将点分十进制IP转换为二进制

In [11]: socket.inet_aton('192.168.1.2')
Out[11]: b'\xc0\xa8\x01\x02'

二进制转换为点分十进制IP

In [12]: socket.inet_ntoa(b'\xc0\xa8\x01\x02')
Out[12]: '192.168.1.2'

域名:

  1. 定义: 网络服务器地址的网络名称

  2. 端口号 : 端口号是网络地址的一部分,在一个系统中 每个网络应用都会有一个端口号相对应。用来在接收消息时确定由谁来接收

    1. 范围 : 1–65535 
      1–255 一些通用的众所周知程序占用 
      256-1023 系统应用端口 
      1024 — 65535 自用 >10000

    2. 获取应用端口

      In [1]: import socket
      
      In [2]: socket.getservbyname('mysql')
      Out[2]: 3306
      
      In [3]: socket.getservbyname('http')
      Out[3]: 80
      
      In [4]: socket.getservbyname('ssh')
      Out[4]: 22
      

传输层服务

1,面向连接的传输服务   ---》tcp协议

  1. 传输特征:
    1. 可靠的数据传输
    2. 可靠性:数据在传输中,无失序,无差错,无丢失,无重复
    3. 在数据传输前和传输结束后需要建立连接和断开连接
  2. 三次握手:在面向连接的传输服务中建立连接的过程
    1. 客户端向服务器发送连接请求
    2. 服务器接收到请求进行确认,返回确认报文
    3. 客户端收到服务器回复最终确认连接
  3. 四次挥手:在面向连接的传输服务中断开连接的过程
    1. 主动方发送报文,告知被动方要断开连接
    2. 被动方回复报文,表示已经接收到请求,准备断开
    3. 被动方再次发送报文,表示准备处理就绪,可以断开
    4. 主动方发送确认报文,断开连接
  4. 应用情况:适用于传输较大的内容或文件,网络良好,需要保证传输可靠性的情况
    1.  e.g.: 聊天信息,文件的上传下载,邮件处理,网页获取

2,面向无法连接的传输服务  ---》udp协议

传输特点:

  1. 不保证传输的可靠性
  2. 没有连接和断开的过程
  3. 数据的首发比较自由
  4. 适用情况可能产生丢包,对传输可靠性要求低
    e.g.:网络视频,群聊,广播等

要求:

  1. 理解三次握手和四次挥手,能够描述过程
  2. 直到tcp和udp传输的区别

socket 套接字编程

  1. 目的
    通过编程语言提供的套接字编程接口,可以更简单的完成基于tcp和udp的编程
  2. 套接字:完成上述目标的一种编程方法
  3. 套接字类别
    1. 流式套接字(SOCK_STREAM):传输层基于tcp的协议通信
         面向连接可靠的传输   tcp的传输   流式套接字
    2. 数据报套接字(SOCK_DGRAM):传输层基于udp协议传输
         面向无连接不可靠的传输  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_type  套接字类型,SOCK_STREAM 流式, SOCK_DGRAM  数据报
  • proto  通常为0  选定子协议类型

返回值:返回套接字对象

2,绑定地址

  • sockfd.bind(addr)
  • 功能:绑定地址
  • 参数:addr  ---》元组(ip,port)('0.0.0.0',1234)(ip,端口号)
     一个元组包含两项 ,第一项为IP第二项为端口号 ,(’172.60.50.50’,8888)

3,设置监听套接字

  • sockfd.listen(n)
  • 功能:将套接字设置为监听套接字,创建监听队列
  • 参数:n是一个正整数 表示监听等待队列的大小
  • *一个监听套接字可以连接多个客户端

4,等待接受客户端连接

  • connfd,addr = sockfd.accept()
  • 功能:阻塞等待处理客户端连接
  • 返回值:coonnfd 新的套接字,用于与客户端通信
  •               addr 连接的客户端的地址(ip,port)
  • *阻塞函数:当程序运行到阻塞函数位置,如果某种条件没有达成则暂停程序运行,直到条件达成结束阻塞

5,消息的收发

  • data = connfd.recv(buffersize)
  • 功能 :接收消息
  • 参数 : 一次最多接收多大的消息  字节
  • 返回值 : 返回接收到的内容
  •  
  • n = connfd.send(data)
  • 功能 : 发送消息
  • 参数 : 要发送的内容  要求bytes格式
  • 返回值 : 返回实际发送的字节数

6,关闭套接字

  • sockfd.close()
  • 功能:关闭套接字 tcp套接字连接断开
  •  telnet  ip   port
from socket import * 

#创建套接字
sockfd = socket(AF_INET,SOCK_STREAM)

#绑定地址
sockfd.bind(('127.0.0.1',8888))

#设置监听
sockfd.listen(5)

#等待客户端连接
print("Waiting for connect...")
connfd,addr = sockfd.accept()
print("Connect from",addr)

#消息收发
data = connfd.recv(1024)
print("Receive:",data.decode())

n = connfd.send(b"Receive your message")
print("send %d bytes"%n)

#关闭套接字
connfd.close()
sockfd.close()

TCP的客户端

  1. 创建套接字(和服务端套接字类型相同)
  2. 发起连接
    1. 格式:connect(addr)
    2. 功能:向服务端发起连接
    3. 参数:服务端地址 元组
  3. 消息收发
  4. 关闭套接字
  5. recv() 特性 
    1. 如果连接双方断开连接,则recv会立即结束阻塞返回空字符串
    2. 当接收缓冲区为空的时候会阻塞
    3. 如果recv一次接收不完缓存去内容,下一次会继续接收
  6. send()特性 
    1. 如果一段不存在,另一端还在试图send操作时会产生BrokenPipeError异常
    2. 当发送缓冲区慢的时候会阻塞
  7. 网络收发缓冲区 
    • 发送和接收消息均先放到缓冲区中,在进行处理 
      即 recv和send实际是从缓冲区接收内容,向缓冲区发送消息
from socket import * 

#创建套接字
sockfd = socket()

#发起连接
sockfd.connect(('127.0.0.1',8888))

#消息收发
msg = input("Msg>>")
sockfd.send(msg.encode())

data = sockfd.recv(1024)
print(data.decode())

sockfd.close()

作业:

1,将要求内容整理话术回答

2,将tcp交互程序改写可以连续的收发消息

from socket import * 

#创建套接字
sockfd = socket(AF_INET,SOCK_STREAM)

#绑定地址
sockfd.bind(('127.0.0.1',9999))

#设置监听
sockfd.listen(5)

while True:
    #等待客户端连接
    print("Waiting for connect...")
    connfd,addr = sockfd.accept()
    print("Connect from",addr)

    while True:
        #消息收发
        data = connfd.recv(1024)
        if not data:
            break
        print("Receive:",data.decode())
        n = connfd.send(b"Receive your message")
        print("send %d bytes"%n)
    #关闭套接字
    connfd.close()

sockfd.close()
from socket import * 

#创建套接字
sockfd = socket()

#发起连接
sockfd.connect(('127.0.0.1',9999))

while True:
    #消息收发
    msg = input("Msg>>")
    if not msg:
        break
    sockfd.sendall(msg.encode())
    data = sockfd.recv(1024)
    print(data.decode())

sockfd.close()

猜你喜欢

转载自blog.csdn.net/qq_42584444/article/details/81448512