网络编程
- 网络目的:数据的传输
- 网络传输是一个复杂的过程
- ISO : 国际标准化组织
OSI七层模型 | 网络通信标准化流程 |
---|---|
应用层 | 提供用户服务,具体内容由特定程序规定 |
表示层 | 数据的压缩优化 |
会话层 | 建立应用连接,选择传输层服务 |
传输层 | 提供不同的传输服务,流量控制 |
网络层 | 路由选择,网络互连 |
链路层 | 提供链路交换,具体消息以帧发送 |
物理层 | 物理硬件,接口,网卡,线路 |
osi七层模型优点:
将功能分开,降低了网络传输中的耦合性,每一部分完成自己的功能.可以在开发和实施的过程中各司其职.
cookie
高内聚 : 单个模块功能尽量单一
低耦合 : 模块之间尽量减少关联和影响网络
四层模型 | – |
---|---|
应用层 | 应用层,表示层,会话层 |
传输层 | 传输层 |
网络层 | 网络层 |
链路层 | 链路层,物理层 |
五层模型 | – |
---|---|
应用层 | 应用层,表示层,会话层 |
传输层 | 传输层 |
网络层 | 网络层 |
链路层 | 链路层 |
物理层 | 物理层 |
协议(网络协议)
在网络通信中,各方必须遵守的规定,包括建立什么样的连接,消息结构等
模块 | 协议 |
---|---|
应用层 | TFTP, HTTP, DNS, SMTP |
传输层 | TCP, UDP |
网络层 | IP |
物理层 | IEEE |
网络基本概念
主机: "localhost" 表示本台计算机
网络上 : 只在本地测试使用
'localhost' '127.0.0.1'
如果想在网络上进行测试
'0.0.0.0' '' '172.60.50.93'
cookie
查看 IP网络信息
linux ifconfig
win ipconfig
获取计算机名称
In [2]: socket.gethostname()
Out[2]: 'tedu'
获取主机IP
In [5]: socket.gethostbyname('localhost')
Out[5]: '127.0.0.1'
IP地址
在网络上用于区分一台计算机
IPv4 : 点分十进制
e.g. 192.168.1.72 0-255
32位二进制表示
IPv6 : 128
网络连接测试命令: ping 172.60.50.92
特殊IP
127.0.0.1 本地测试IP
0.0.0.0 本地网卡通用IP
192.168.1.0 表示当前网段
192.168.1.1 表示网关
192.168.1.255 广播地址
获取服务主机信息
In [7]: socket.gethostbyaddr("www.baidu.com")
Out[7]: ('127.0.0.1', [], ['119.75.213.61'])
主机 别名 IP地址
将ip十进制转化为二进制
In [12]: socket.inet_aton("192.168.1.2")
Out[12]: b'\xc0\xa8\x01\x02'
将ip二进制转化为十进制
In [11]: socket.inet_ntoa(b"\xc0\xa8\x01\x02")
Out[11]: '192.168.1.2'
域名 : 网络服务器IP地址的名称
url : 在网络上定位某个资源位置的字串
端口号 : 端口号是网络地址的一部分,在一个系
统中,每个网络应用都会有一个唯一的端口号,
取来区别其他应用,接受发往这个端口的消息。
数字范围 : 1--65535
1--255 : 一些众所周知的端口
256--1023 : 系统应用
1024---65535 : 自用
推荐 >10000 8888 9999 7777 6666
测试一个软件端口号
In [13]: socket.getservbyname('mysql')
Out[13]: 3306
传输层服务
面向连接的传输服务 –> TCP协议
- 传输特征
- 提供可靠的传输服务
- 可靠性表现 : 数据在传输过程中,无失序,无差错,无重复,无丢失
- 提供可靠的传输服务
- 传输过程中有建立和断开连接的过程
- 三次握手:建立数据传输两端的持续连接
- 客户端向服务器发起连接请求
- 服务器收到连接请求进行确认,返回报文
- 客户端收到服务器确认进行连接创建
- 四次挥手:断开连接的两端,保证数据的传输完整
- 主动方发送报文,告诉被动方要断开连接
- 被动方返回报文,告知收到请求,准备断开
- 被动方再次发送报文,告知准备完毕可以断开
- 主动方发送报文完成断开
- 三次握手:建立数据传输两端的持续连接
适用情况:文件的上传下载,网络情况良好,需要必须保证可靠性的情况
比如:信息聊天,文件上传下载,邮件,网页获取
面向无连接的传输服务 –> UDP协议
- 传输特征
- 不保证传输的可靠性
- 无需建立三次握手和四次挥手的连接断开过程
- 消息的收发比较自由,不受其他约束
适用情况: 网络情况较差,对可靠性要求不高,收发消息的两端不适合建立固定连接
比如:网络视频,群聊,发送广播
问题总结
- osi模型
- 三次握手和四次挥手
- TCP和UDP的区别
socket套接字编程
目的:通过编程语言提供的函数接口进行组合,更简单的完成基于TCP和UDP通信的网络编程
套接字:完成上述目标的编程方案
套接字的分类 | – |
---|---|
流式套接字(SOCK_STREAM) | 传输层基于TCP的协议进行通信 |
数据报套接字(SOCK_DGRAM) | 传输层基于UDP的协议进行传输 |
底层套接字(SOCK_RAM) | 访问底层协议的套接字 |
TCP套接字
import socket
#创建套接字
#参数:
# socket_family 选择地址族类型AF_INET表示IPv4
# socket_type 选择套接字类型 SOCK_STREAM流式
#SOCK_DGRAM数据报
#proto 通常为0(表示选择子协议)
socket.socket(socket_family = AF_INET,
socket_type = SOCK_STREAM,
proto = 0)
#绑定IP端口
#参数:二元元组,第一项为IP,第二项为端口
sockefd.bind("192.168.1.2",8888)
#将套接字设置为可监听
#功能:将套接字设置为监听套接字,并设置监听队列
#参数:监听对象的大小,n为大于0的正整数
sockfd.listen(n)
#等待客户端连接
#功能:阻塞等待客户端连接
#返回值:connfd 一个新的套接字,用于和指定客户端通信
# addr 连接的客户端的地址
'''
阻塞函数:程序运行到阻塞函数位置,如果某种预期
条件没有达成则暂停继续运行,直到条件达成后再继续运行
'''
connfd,addr = sockfd.accept()
#消息收发
#功能:接收消息
#参数:每次最多接收的消息大小bytes
#返回值:返回接收到的内容 decode()
data = connfd.recv(buffersize)
#发送消息
#参数:要发送的内容,必须是bytes格式 encode()
#返回值:实际发送的字节数
n = connfd.send(data)
#关闭套接字
#功能:关闭套接字,TCP连接断开
close()
TCP客户端
from socket import *
#创建套接字
#通信的两端套接字类型相同
sockfd = socket(AF_INET,SOCK_STREAM)
#发起连接
#元组,服务器端的地址
sockfd.connect(("192.168.1.2",8888))
#收发消息
#两端收发需要配合
sockfd.send()
#接收消息
sockfd.recv()
#关闭套接字
sockfd.close()