python 网络编程

OSI七层模型和TCP四层模型

OSI七层网络模型解释说明TCP/IP四层网络模型对应协议
应用层为应用程序提供服务应用层HTTP\TFTP\FTP\NFS\WAIS\SMTP
表示层数据格式转化、数据加密Telnet、Rlogin、SNMP、Gopher
会话层建立管理和维护会话SMTP、DNS
传输层建立、管理和维护端到端的连接传输层TCP、UDP
网络层IP选址以及路由选择网络层IP、ICMP、ARP、RARP、AKP、UUCP
数据链路层提供介质访问和链路管理数据链路层FDDI、Ethernet、Arpanet、PDN、SLIP、PPP
物理层物理层IEEE 802.A、IEEE 802.2到IEEE 802.11

UDP编程

socket的介绍以及创建套接字和关闭套接字

1.不同电脑上的进程之间如何通信
网络层的“ip地址”可以唯一标识网络中的主机,而传输层的“协议+端口”可以唯一标识主机中的应用进程(进程)。这样利用ip地址,协议,端口就可以标识网络的进程了,网络中的进程通信就可以利用这个标志与其它进程进行交互。
2.什么是socket
socket(简称套接字) 是进程间通信的一种方式,它与其他进程间通信的一个主要不同是:
它能实现不同主机间的进程间通信,我们网络上各种各样的服务大多都是基于 Socket 来完成通信的. 例如我们每天浏览网页、QQ 聊天、收发 email 等等

步骤:
1 .创建套接字:
1)导入模块
2)创建套接字:
函数 socket.socket
创建一个 socket,该函数带有两个参数:
import socket
socket.socket(AddressFamily, Type)
Address Family:可以选择 AF_INET(用于 Internet 进程间通信) 或者 AF_UNIX(用于同一台机器进程间通信),实际工作中常用AF_INET
Type:套接字类型,可以是 SOCK_STREAM(流式套接字,主要用于 TCP 协议)或者 SOCK_DGRAM(数据报套接字,主要用于 UDP 协议)
socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
3)创建通信地址和端口:IP和端口:元组
2.收/发数据
1)发数据sendto(信息,接收地址)
2)接数据:recvfrom(长度):接受的是一个元组,信息和地址
recv(长度).
3.关闭套接字
s.close().

import socket 
s = socket(AF_INET, SOCK_DGRAM)
addr = ('192.168.1.164', 1123)
s.bind(addr)    # 固定端口
while True:
    reply = s.recvfrom(1024)
    print('%s : %s' % (str(reply[1]), reply[0].decode('utf-8')))
    msg = input('请输入回复信息:')
    s.sendto(msg.encode('utf-8'), reply[1])
udp通信流程介绍

UDP则是面向无连接的协议。

数据包就是这种形式。比如:短信。只要数据发送出去, 无需去管对方是否接收到。

使用UDP协议时,不需要建立连接,只需要知道对方的IP地址和端口号,就可以直接发数据包。但是,能不能到达就不知道了。

虽然用UDP传输数据不可靠,但它的优点和TCP比,速度快,对于不要求可靠到达的数据,就可以使用UDP协议。
创建一个基于udp的网络程序流程很简单,具体步骤如下:

  1. 创建客户端套接字
  2. 发送/接收数据
  3. 关闭套接字
    请添加图片描述
创建udp客户端套接字和网络调试助手之间实现模拟通信
from socket import *

# 1. 创建udp套接字
udp_socket = socket(AF_INET, SOCK_DGRAM)

# 2. 准备接收方的地址
dest_addr = ('192.168.236.129', 8080)

# 3. 从键盘获取数据
send_data = input("请输入要发送的数据:")

# 4. 发送数据到指定的电脑上
udp_socket.sendto(send_data.encode('utf-8'), dest_addr)

# 5. 等待接收对方发送的数据
recv_data = udp_socket.recvfrom(1024)  # 1024表示本次接收的最大字节数

# 6. 显示对方发送的数据
# 接收到的数据recv_data是一个元组
# 第1个元素是对方发送的数据
# 第2个元素是对方的ip和端口
print(recv_data[0].decode('gbk'))
print(recv_data[1])

# 7. 关闭套接字
udp_socket.close()

TCP编程

tcp通信流程介绍

TCP协议,传输控制协议(英语:Transmission Control Protocol,缩写为 TCP)是一种面向连接的、可靠的、基于字节流的传输层通信协议,由IETF的RFC 793定义。

TCP通信需要经过创建连接、数据传送、终止连接三个步骤。

TCP通信模型中,在通信开始之前,一定要先建立相关的连接,才能发送数据,类似于生活中,“打电话”。

这种连接是一对一的,因此TCP不适用于广播的应用程序,基于广播的应用程序请使用UDP协议。
请添加图片描述

三次握手和四次挥手
  • TCP的三次握手(建立连接)和四次挥手(关闭连接)
  • 位码即tcp标志位,有6种标识:
    • SYN(synchronous建立联机)
    • ACK(acknowledgement 确认)
    • PSH(push传送)
    • FIN(finish结束)
    • RST(reset重置)
    • URG(urgent紧急)
  • 在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接,如图所示。
    1. 第一次握手:建立连接时,客户端A发送SYN包(SYN=j)到服务器B,并进入SYN_SEND状态,等待服务器B确认。
    2. 第二次握手:服务器B收到SYN包,必须确认客户A的SYN(ACK=j+1),同时自己也发送一个SYN包(SYN=k),即SYN+ACK包,此时服务器B进入SYN_RECV状态。
    3. 第三次握手:客户端A收到服务器B的SYN+ACK包,向服务器B发送确认包ACK(ACK=k+1),此包发送完毕,客户端A和服务器B进入ESTABLISHED状态,完成三次握手。
      如图所示,完成三次握手,客户端与服务器开始传送数据:
      请添加图片描述
      由于TCP连接是全双工的,因此每个方向都必须单独进行关闭。这个原则是当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向的连接。收到一个 FIN只意味着这一方向上没有数据流动,一个TCP连接在收到一个FIN后仍能发送数据。首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。
  1. 客户端A发送一个FIN,用来关闭客户A到服务器B的数据传送。
  2. 服务器B收到这个FIN,它发回一个ACK,确认序号为收到的序号加1。和SYN一样,一个FIN将占用一个序号。
  3. 服务器B关闭与客户端A的连接,发送一个FIN给客户端A。
  4. 客户端A发回ACK报文确认,并将确认序号设置为收到序号加1。

如图所示,TCP采用四次挥手关闭连接:
请添加图片描述

创建tcp客户端套接字和网络调试助手之间实现模拟通信

1.导入模块
2.创建套接字
3.连接
4.收/发消息
5.关闭套接字

from socket import *
client_socket = socket(AF_INET, SOCK_STREAM)
sever_addr = ('192.168.1.164', 8080)
client_socket.connect(sever_addr)
while True:
    msg = input('请输入发送信息:')
    if msg == 'exit':
        break
    client_socket.send(msg.encode('utf-8'))
    reply = client_socket.recv(1024)
    print('%s:%s' % (sever_addr, reply.decode('gbk')))
client_socket.close()
创建tcp服务端端套接字和网络调试助手之间实现模拟通信

tcp服务器端步骤:
1.导入模块
2.创建服务器端套接字
3.绑定ip和端口
4.监听
5.接受客户端套接字
6.收/发消息
7.关闭客户端套接字
8.最后关闭服务器套接字

from socket import *
server_socket = socket(AF_INET, SOCK_STREAM)
s_addr = ('192.168.1.164', 9632)
server_socket.bind(s_addr)
server_socket.listen(50)
client, c_addr = server_socket.accept()
while True:
    reply = client.recv(1024)
    if reply.decode('gbk') == 'exit':
        print(reply.decode('gbk'))
        break
    msg = input('回复信息:')
    client.send(msg.encode('utf-8'))
client.close()
server_socket.close()

HTTP协议

浏览器访问服务器的过程

请添加图片描述

  • 用户输入网址.
  • 浏览器请求DNS服务器, 获取域名对应的IP地址.
  • 请求连接该IP地址服务器.
  • 发送资源请求. (HTTP协议)
  • web服务器接收到请求, 并解析请求, 判断用户意图.
  • 获取用户想要的资源.
  • 将资源返回给web服务器程序.
  • web服务器程序将资源数据通过网络发送给浏览器.
  • 浏览器解析请求的数据并且完成网页数据的显示.
域名和DNS
  • 我们在访问一台服务器的时候, 需要记住该服务器的IP地址, 由于IP地址不利于人们记忆, 所以推出的域名技术. 域名是由一串用点分隔的名字组成的 Internet 上某一台计算机或计算机组的名称, 用于在数据传输时标识计算机的位置.
  • 域名可以用来表示一个单位、机构或可以利用个人在 Internet上 的确定的名称或位置. 域名是惟一的. 客户可以利用这个名字找寻有关的产品和服务信息.
  • 由于我们用域名来标识计算机的位置, 但是我们前面讲过, 网络上标识主机的唯一标识是IP地址, 所以就需要记录一下, 一个域名和IP地址的对应关系, 这个对应关系就存储在DNS服务器中, 当我们向 DNS 发出请求时,DNS会返回给我们域名所对应的IP地址.
TTP协议简介及与原理介绍
  1. HTTP协议介绍
    超文本传输协议,是一个基于请求与响应,无状态的,应用层的协议,常基于TCP/IP协议传输数据,互联网上应用最为广泛的一种网络协议,所有的WWW文件都必须遵守这个标准。设计HTTP的初衷是为了提供一种发布和接收HTML页面的方法。
    2.HTTP工作流程
    超文本传输协议(HTTP)是万维网应用层的协议,是通过两个程序实现:
  • 一个是客户端程序(一般称为浏览器)
  • 另一个是服务器 (常称Web服务器)

这两个通常运行在不同的主机上,通过交换HTTP报文来完成网页请求和响应;并且HTTP定义了报文的结构和客户/服务器之间交换报文的规则。
HTTP 协议规定,请求从客户端发出,最后服务器端响应该请求并返回。换句话说,肯定是先从客户端开始建立通信的,服务器端在没有接收到请求之前不会发送响应。

HTTP请求报文格式(请求行、请求头、请求体)
  1. HTTP 请求报文介绍

HTTP最常见的请求报文有两种:

  1. GET 方式的请求报文
  2. POST 方式的请求报文

说明:

  • GET: 获取web服务器数据
  • POST: 向web服务器提交数据
  1. HTTP GET 请求报文分析

HTTP GET 请求报文效果图:
请添加图片描述

GET 请求报文说明:
---- 请求行 ----
GET / HTTP/1.1  # GET请求方式 请求资源路径 HTTP协议版本
---- 请求头 -----
Host: www.baidu.com  # 服务器的主机地址和端口号,默认是80
Connection: keep-alive # 和服务端保持长连接
Upgrade-Insecure-Requests: 1 # 让浏览器升级不安全请求,使用https请求
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36  # 用户代理,也就是客户端的名称
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8 # 可接受的数据类型
Accept-Encoding: gzip, deflate # 可接受的压缩格式
Accept-Language: zh-CN,zh;q=0.9 #可接受的语言
Cookie: pgv_pvi=1246921728; # 登录用户的身份标识

---- 空行 ----

GET 请求原始报文说明:

GET / HTTP/1.1\r\n
Host: www.baidu.com\r\n  
Connection: keep-alive\r\n
Upgrade-Insecure-Requests: 1\r\n
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36\r\n
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8\r\n
Accept-Encoding: gzip, deflate\r\n
Accept-Language: zh-CN,zh;q=0.9\r\n
Cookie: pgv_pvi=1246921728; \r\n
\r\n  (请求头信息后面还有一个单独的’\r\n’不能省略)

说明:

  • 每项数据之间使用:\r\n
HTTP POST 请求报文分析

HTTP POST 请求报文效果图:
请添加图片描述
请求体效果图:
请添加图片描述
POST 请求报文说明:

---- 请求行 ----
POST /v2/api/?login HTTP/1.1 # POST请求方式 请求资源路径 HTTP协议版本
---- 请求头 ----
Host: passport.baidu.com # 服务器的主机地址和端口号,默认是80
Connection: keep-alive # 和服务端保持长连接
Content-Type: application/x-www-form-urlencoded  # 告诉服务端请求的数据类型
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36 # 客户端的名称
---- 空行 ----
---- 请求体 ----
username=hello&pass=hello # 请求参数

POST 请求原始报文说明:

POST /v2/api/?login HTTP/1.1\r\n
Host: passport.baidu.com\r\n
Connection: keep-alive\r\n
Content-Type: application/x-www-form-urlencoded\r\n
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36\r\n
\r\n(请求头信息后面还有一个单独的'\r\n'不能省略)
username=hello&pass=hello

说明:

  • 每项数据之间使用:\r\n
小结
  • 一个HTTP请求报文可以由请求行、请求头、空行和请求体4个部分组成。
  • 请求行是由三部分组成:
    1.请求方式
    2.请求资源路径
    3.HTTP协议版本
  • GET方式的请求报文没有请求体,只有请求行、请求头、空行组成。
  • POST方式的请求报文可以有请求行、请求头、空行、请求体四部分组成,注意:POST方式可以允许没有请求体,但是这种格式很少见。

GET和POST请求对比效果图:

请添加图片描述

HTTP响应报文格式(响应行、响应头、响应体)

HTTP响应报文分析

HTTP 响应报文效果图:
请添加图片描述
请添加图片描述
响应报文说明:

--- 响应行/状态行 ---
HTTP/1.1 200 OK # HTTP协议版本 状态码 状态描述
--- 响应头 ---
Server: Tengine # 服务器名称
Content-Type: text/html; charset=UTF-8 # 内容类型
Transfer-Encoding: chunked # 发送给客户端内容不确定内容长度,发送结束的标记是0\r\n, Content-Length表示服务端确定发送给客户端的内容大小,但是二者只能用其一。
Connection: keep-alive # 和客户端保持长连接
Date: Fri, 23 Nov 2018 02:01:05 GMT # 服务端的响应时间
--- 空行 ---
--- 响应体 ---
<!DOCTYPE html><html lang=“en”> …</html> # 响应给客户端的数据

原始响应报文说明:

HTTP/1.1 200 OK\r\n
Server: Tengine\r\n
Content-Type: text/html; charset=UTF-8\r\n
Transfer-Encoding: chunked\r\n
Connection: keep-alive\r\n
Date: Fri, 23 Nov 2018 02:01:05 GMT\r\n
\r\n(响应头信息后面还有一个单独的’\r\n’不能省略)
<!DOCTYPE html><html lang=“en”> …</html>

说明:

每项数据之间使用:\r\n

HTTP 状态码介绍

HTTP 状态码是用于表示web服务器响应状态的3位数字代码

状态码说明
200请求成功
307重定向
400错误的请求,请求地址或者参数有误
404请求资源在服务器不存在
500服务器内部源代码出现错误
小结

请添加图片描述

  • 一个HTTP响应报文是由响应行、响应头、空行和响应体4个部分组成。
  • 响应行是由三部分组成:HTTP协议版本 状态码 状态描述,最常见的状态码是200
HTTP网络请求模块
  1. Python中实现HTTP网络请求常用的三个模块
    • urllib
    • urllib3
    • requests
  2. urllib模块
    • urllib提供了一系列用于操作URL的功能。
    • urllib的request模块可以非常方便地抓取URL内容,也就是发送一个GET请求到指定的页面,然后返回HTTP的响应。
      代码示例:
import urllib.request

response = urllib.request.urlopen('https://www.baidu.com')

headers = response.getheaders()  # 获取响应头部信息
for k, v in headers:
    print('%s: %s' % (k, v))

html = response.read() # 获取网页源码
print(html.decode())

运行结果:

Accept-Ranges:bytes
Cache-Control:no-cache
Content-Length:227
Content-Type:text/html
Date:Sat, 26 Nov 2022 03:30:25 GMT
P3p:CP=" OTI DSP COR IVA OUR IND COM "
P3p:CP=" OTI DSP COR IVA OUR IND COM "
Pragma:no-cache
Server:BWS/1.1
Set-Cookie:BD_NOT_HTTPS=1; path=/; Max-Age=300
Set-Cookie:BIDUPSID=0656CCE60DF708E08086E0DBFC6135EF; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com
Set-Cookie:PSTM=1669433425; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com
Set-Cookie:BAIDUID=0656CCE60DF708E03C3E92BE8A969E69:FG=1; max-age=31536000; expires=Sun, 26-Nov-23 03:30:25 GMT; domain=.baidu.com; path=/; version=1; comment=bd
Strict-Transport-Security:max-age=0
Traceid:1669433425237298612214254512446970482199
X-Frame-Options:sameorigin
X-Ua-Compatible:IE=Edge,chrome=1
Connection:close
<html>
<head>
	<script>
		location.replace(location.href.replace("https://","http://"));
	</script>
</head>
<body>
	<noscript><meta http-equiv="refresh" content="0;url=http://www.baidu.com/"></noscript>
</body>
</html>
  • 11
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值