十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
这篇文章将为大家详细讲解有关PyThon3中网络编程基础实例,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。
在赤坎等地区,都构建了全面的区域性战略布局,加强发展的系统性、市场前瞻性、产品创新能力,以专注、极致的服务理念,为客户提供成都做网站、成都网站设计、成都外贸网站建设 网站设计制作按需设计网站,公司网站建设,企业网站建设,品牌网站设计,成都全网营销推广,外贸营销网站建设,赤坎网站建设费用合理。
编写一个最简单的Client/Server程序:
1、首先执行下面命令开启一个监听8000端口的HTTP服务器:
python3 -m http.server 8000
Serving HTTP on 0.0.0.0 port 8000 ...
2、接着编写一个程序,来对这个服务器发起HTTP请求:
import requests r = requests.get('http://127.0.0.1:8000/') print(r)
3、再执行这个程序:
bash-3.2$ python test.py
显示服务器返回了一个200成功响应。
现在我们来总结请求过程:
客户端向服务器端发起了一个HTTP(GET)请求。
服务器端向客户端返回了一个HTTP(200)响应。
这是我们能看到的最抽象的过程,下面再用tcpdump细看发生了什么:
在命令行用tcpdump来监听本地网卡的tcp连接。
tcpdump -i lo0 port 8000
再通过wireshark来观察结果:
tcpdump -i lo0 port 8000 -w test.cap
现在执行程序:
bash-3.2$ python test.py
得到结果:
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on lo0, link-type NULL (BSD loopback), capture size 262144 bytes 23:46:06.464962 IP localhost.49329 > localhost.irdmi: Flags [S], seq 1191154495, win 65535, options [mss 16344,nop,wscale 5,nop,nop,TS val 178410641 ecr 0,sackOK,eol], length 0 23:46:06.465018 IP localhost.irdmi > localhost.49329: Flags [S.], seq 1405387906, ack 1191154496, win 65535, options [mss 16344,nop,wscale 5,nop,nop,TS val 178410641 ecr 178410641,sackOK,eol], length 0 23:46:06.465029 IP localhost.49329 > localhost.irdmi: Flags [.], ack 1, win 12759, options [nop,nop,TS val 178410641 ecr 178410641], length 0 23:46:06.465039 IP localhost.irdmi > localhost.49329: Flags [.], ack 1, win 12759, options [nop,nop,TS val 178410641 ecr 178410641], length 0 23:46:06.465065 IP localhost.49329 > localhost.irdmi: Flags [P.], seq 1:146, ack 1, win 12759, options [nop,nop,TS val 178410641 ecr 178410641], length 145 23:46:06.465079 IP localhost.irdmi > localhost.49329: Flags [.], ack 146, win 12754, options [nop,nop,TS val 178410641 ecr 178410641], length 0 23:46:06.467141 IP localhost.irdmi > localhost.49329: Flags [P.], seq 1:156, ack 146, win 12754, options [nop,nop,TS val 178410642 ecr 178410641], length 155 23:46:06.467171 IP localhost.49329 > localhost.irdmi: Flags [.], ack 156, win 12754, options [nop,nop,TS val 178410643 ecr 178410642], length 0 23:46:06.467231 IP localhost.irdmi > localhost.49329: Flags [P.], seq 156:5324, ack 146, win 12754, options [nop,nop,TS val 178410643 ecr 178410643], length 5168 23:46:06.467245 IP localhost.49329 > localhost.irdmi: Flags [.], ack 5324, win 12593, options [nop,nop,TS val 178410643 ecr 178410643], length 0 23:46:06.467313 IP localhost.irdmi > localhost.49329: Flags [F.], seq 5324, ack 146, win 12754, options [nop,nop,TS val 178410643 ecr 178410643], length 0 23:46:06.467331 IP localhost.49329 > localhost.irdmi: Flags [.], ack 5325, win 12593, options [nop,nop,TS val 178410643 ecr 178410643], length 0 23:46:06.468442 IP localhost.49329 > localhost.irdmi: Flags [F.], seq 146, ack 5325, win 12593, options [nop,nop,TS val 178410644 ecr 178410643], length 0 23:46:06.468479 IP localhost.irdmi > localhost.49329: Flags [.], ack 147, win 12754, options [nop,nop,TS val 178410644 ecr 178410644], length 0
通过结果可得:
客户端发起一个SYN报文,向服务器请求建立一个TCP连接。
服务器端返回一个SYN+ACK报文,表示服务器收到了客户端传来的请求,并同意与客户端建立TCP连接。
客户端返回一个ACK报文,表示已经知道服务器同意建立TCP连接,这时候双方开始通信。
客户端和服务器端不断地交换信息,接收报文,返回应答。
最后数据传输完毕,服务器发起一个FIN报文,表示要结束通信,客户端返回一个ACK应答,接着又发送一个FIN报文,最后服务器端返回一个ACK应答,此时连接过程结束。
现在再来看服务器端的状态,通过lsof命令来查看绑定8000端口的描述符信息:
lsof -n -i:8000 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME python3.4 1128 tonnie 4u IPv4 0x17036ae156ec58cf 0t0 TCP *:irdmi (LISTEN)
现在用刚才的例子来解释TCP中状态迁移的概念,这时候,如果从客户端到来一个请求:
服务器端接收到客户端的SYN报文,返回SYN+ACK报文,服务器端进入SYN_RCVD状态。 服务器端收到客户端返回的ACK应答后,连接建立,进入ESTABLISHED状态。 服务器端的数据传输完毕,给客户端发送FIN报文,进入FIN_WAIT_1状态。 服务器端接收到客户端返回的ACK应答后,进入FIN_WAIT_2状态。 服务器端接收到客户端的FIN报文,接着返回一个ACK应答,等待连接关闭,进入TIME_WAIT状态。 服务器端经过2MSL时间后进入CLOSED状态,此时连接关闭。
在上面的程序中,客户端与服务器端的通信都要经过四个层(应用层、传输层、网络层、网络接口层)来打交道。那么这段Python程序都是通过socket操作连接的建立和关闭以及数据的传输等一系列方法。
客户端最简化代码:
import socket sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect(('127.0.0.1', 8000)) sock.send(b'GET / HTTP/1.1\r\nHost: 127.0.0.1:8000\r\n\r\n') data = sock.recv(4096) print(data) sock.close()
服务器端最简化代码:
import socket sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sock.bind(('127.0.0.1', 8000)) sock.listen(5) while 1: cli_sock, cli_addr = sock.accept() req = cli_sock.recv(4096) cli_sock.send(b'hello world') cli_sock.close()
关于PyThon3中网络编程基础实例就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。