Network Programming 网络编程¶
一、网络通讯¶
网络通讯概述¶
- 多方链接,数据传递
IP地址¶
用途
- 唯一标记网络中一个终端
组成
- 网络地址
- 主机地址
分类
-
IPV4
-
A类
- 1Byte网络地址 + 3Byte主机地址, 最高位为0
- 1.0.0.1-126.255.255.254
-
B类
- 2Byte网络地址 + 2Byte主机地址, 最高位为10
- 128.1.0.1-191.255.255.254
-
C类
- 3Byte网络地址 + 1Byte主机地址, 最高位为110
- 192.0.1.1-223.255.255.254
-
D类
- 最高位为1110
- 保留地址,不制定特定网络,多用于多点广播
- 224.0.0.1-239.255.255.254
-
E类
- 以“1111”开始,为将来使用保留
- 仅用于实验和开发
-
私有IP
- IP地址仅用于局域网使用,不可在公网中使用
- 10.0.0.0~10.255.255.255
- 172.16.0.0~172.31.255.255
- 192.168.0.0~192.168.255.255
-
-
IPV6
-
其他
- IP地址127.0.0.1 ~ 127.255.255.255 用于回路测试
- 127.0.0.1 代表本地IP地址,那么,
http://127.0.0.1就可测试本机配置的Web服务器
端口Port¶
- 应用门户
-
端口号
- 0 - 65535
-
分配
-
知名端口
- 0到1023
- 80端口分配给HTTP服务
- 21端口分配给FTP服务
-
动态端口
- 1024到65535
- 主机分配可用端口,而后随程序结束而释放
-
查看
netstat -an
socket¶
-
不同电脑的进程间通讯
- PID?
- IP地址 + 端口
-
基本概念
- 进程间通讯的一种方式
-
实践
-
创建套接字
import socket sock = socket.socket(AddressFamily, Type) sock.close()- Address Family:可以选择
- AF_INET(用于 Internet 进程间通信,实际工作**常用**)
- AF_UNIX(用于同一台机器进程间通信)
- Type:套接字类型
- SOCK_STREAM(流式套接字,主要用于 TCP 协议)
- SOCK_DGRAM(数据报套接字,主要用于 UDP 协议)
- Address Family:可以选择
-
-
使用流程
- 创建套接字
- 使用套接字收/发数据
- 关闭套接字
二、UDP网络程序¶
- 具体步骤
- 端口绑定问题解决
三、TCP网络程序¶
-
基本概念
- 传输控制协议Transmission Control Protocol
- 面向连接的、可靠的、基于字节流的传输层通信协议
-
特点
- 面向连接
-
可靠传输
-
发送应答机制
- ACK
-
超时重传
- RTT
-
错误校验
- 流量控制和阻塞管理
-
-
通讯模型
- 打电话
TCP客户端¶
TCP服务器¶
-
基本流程
- socket创建一个套接字
- bind绑定ip和port
- listen使套接字变为可以被动链接
- accept等待客户端的链接
- recv/send接收发送数据
TCP 注意点¶
- 服务器端口绑定
三次握手,四次挥手¶
- 三次握手,四次挥手都是在tcp协议中发生的,这种协议是全双工通信协议,即允许数据同时在两个方向上同时传输,同时进行收发操作。
- 而三次握手,四次挥手两者都是客户端首先发送相关命令信息。这与端口的绑定有关。
三次握手:是为了客户端与服务端都准备好的连接工作
- 客户端在连接服务器时进行堵塞,发送syn number标志。
- 而后服务器端接受到信息进行应答, 准备好资源。发送 ack number + 1;同时也向客户端发送syn num的信息
- 而后客户端接收到信息,将Num + 1后回送给服务器端
四次挥手:是为了客户端与服务端都进行资源的释放操作
- 连接断开的时候,客户端先发送连接套接字关闭的命令,
- 而后服务器端在接收到关闭命令之后,发送关闭接受命令回送信息。
- 再然后,会调用子套接字的关闭命令,发送给客户端,进行关闭发送命令。
- 客户端接收到服务器的关闭命令后,进行延迟2msl时间延迟操作,同时回送已接收到关闭命令的信息。在这个过程中,如果服务器端没有接收到回送信息,则会重复再发送子套接字关闭发送的命令。
可以设置服务器的套接字可以重复利用之前的资源。
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
TCP 长断连接¶
- 现在的网站连接都是利用长连接,以减少服务器的资源。短连接使用需要耗费大量的资源
四、网络抓包¶
wireshark¶
五、TCP/IP协议¶
TCP/IP简介¶
-
协议
-
网络协议
-
TCP/IP协议簇
-
常用网络协议
六、网络通讯过程¶
-
两台电脑通讯
- IP地址处于同一网段
-
集线器组成网络
-
缺点
- 广播发送,容易网络拥堵
-
-
交换机组成网络
- 即可广播,也可单播
-
路由器连接多网络
通讯过程¶
-
首先去系统缓存文件中寻找是否有域名对应的ip地址,如果没有则需要去访问DNS服务器获取该域名对应的IP地址。
- 电脑去系统缓存文件中查看是否有默认网关(路由器)的Mac地址,arp -a
- 如果有,直接使用。如果没有则使用arp协议广播获取路由器的Mac地址
- 依据DNS服务器的IP地址,发送请求解析对应的域名
- 而后,通过默认网关以及互联网的层层转发到达DNS域名服务器,获得请求并应答回递。
-
知道了域名服务器对应的IP地址,之后则向域名对应的IP地址发送三次握手连接请求。连接成功。
- 而后服务器进行HTTP协议数据应答。
- 之后便可以通过客户端进行相应的HTTP的请求数据发送以及等待服务器的相关应答操作。
- 访问结束后,客户端与服务器进行TCP的四次挥手。双方进行相关操作资源的释放。
当然,期间还有路由器之间的发射协议
网络地址转换器NET¶
七、Http 协议¶
八、Web并发服务器¶
Epoll原理¶
当进程单线程实现高并发: - kernel: 操作系统拥有独有的核心空间
单进程单线程瓶颈: - 将服务器内部的套接字进行复制FD(文件描述符)后,让操作系统检查FD内部是否有新消息到达
共享的内存空间中进行检查: - 减少复制的内存时间 - 以事件通知的方式进行检查,而非轮询检查。
import epoll
# 1. 创建epoll对象
epoll = select.epoll()
# 将监听套接字对应的ID注册到epoll中
epoll.register(server_socket.fileno(), select.EPOLLIN)
while True:
# 默认堵塞,直到OS检测到数据来,通过事件通知的方式进行告诉这个程序,此时才会解堵塞。
# return: [(fd, event), (fd2, event2), (fd3, event3)]
fd_event_list = epoll.poll()
# [(fd, event), (套接字对应的文件描述符,这个文件描述符到底是什么事件,例如可以调用recv接收等)]
for fd, event in fd_event_list:
if fd == server_socket.fileno():
# 判断新客户端连接到来
client_socket, client_addr = server_socket.accept()
epoll.register(client_socket.fileno(), select.EPOLLIN)
# 添加字典,从文件描述符获取到套接字
fd_event_dict[client_socket.fileno()] = client_socket
elif event = select.EPOLLIN:
# 判断已经连接的客户端有数据发送过来
recv_data = fd_event_dict[fd].recv(128).decode("utf-8")
if recv_data:
# 有数据消息
service_client(fd_event_dict[fd], recv_data)
else:
# 没有消息,客户端主动关闭
fd_event_dict[fd].close()
epoll.unresigster(fd)
del fd_event_dict[fd]