知行编程网知行编程网  2022-11-10 21:30 知行编程网 隐藏边栏  3 
文章评分 0 次,平均分 0.0
导语: 本文主要介绍了关于PyThon3学习须知:网络编程基础实例的相关知识,希望可以帮到处于编程学习途中的小伙伴

PyThon3学习指导:网络编程基础实例

在学习python网络编程的时候,过于生硬、难以理解的知识点总是让我们需要看别人对这个领域的总结思路。通过示例操作通常更容易理解。下面分享最基本的网络编程示例内容。



编写一个最简单的Client/Server程序:

1、首先执行以下命令,启动一个HTTP服务器监听8000端口:


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
<Response [200]>


显示服务器返回了一个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
<Response [200]>


得到结果:

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()


以上就是python网络编辑最简单的基础内容了。你可以消化和学习。如果你想了解更多关于python网络编程的知识,请点击进入



本文为原创文章,版权归所有,欢迎分享本文,转载请保留出处!

知行编程网
知行编程网 关注:1    粉丝:1
这个人很懒,什么都没写
扫一扫二维码分享