http tcp socket等一些基本概念
tcp&http
TCP/IP 协议是传输层协议,主要解决数据在网路中如何传输的问
HTTP 协议是应用层协议,主要解决如何包装数据,是基于TCP连接的。
问题1:tcp如何建立连结?
tcp三次握手
第一次握手:客户端发送syn包(SYN=j)到服务器,并进入SYN_SEND状态,等待服务器的确认。
第二次握手:服务器收到syn包,必须确认客户的SYN(ACK=j+1),同时自己也要自己发送SYN包(SYN=k),即SYN+ACK包,此时服务器进入SYN_RECV状态。
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ACK=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。
那么这三次握手具体怎么实现的呢?
要实现tcp连结,操作系统提供了socket
socket 规定了如何去实现TCP连接,是对TCP进行封装成unix哲学(一切皆文件)(打开-读/写-关闭)
# 导入socket库:
import socket
# 创建一个socket:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 建立连接:
s.connect(('www.sina.com.cn', 80))
s.connect(('www.sina.com.cn', 80))就是建立TCP连接了
然后就可以发送HTTP请求了
# 发送数据:
s.send(b'GET / HTTP/1.1\r\nHost: www.sina.com.cn\r\nConnection: close\r\n\r\n')
发送的文本符合HTTP协议,那么就是HTTP请求,对方服务器会返回数据给你,是符合HTTP协议的响应
# 接收数据:
buffer = []
while True:
# 每次最多接收1k字节:
d = s.recv(1024)
if d:
buffer.append(d)
else:
break
data = b''.join(buffer)
所有数据都以二进制形式都存在buffer里面了,那么我们把它解析出来
响应分为响应头和响应体
header, html = data.split(b'\r\n\r\n', 1)
print(header.decode('utf-8'))
# 把接收的数据写入文件:
with open('sina.html', 'wb') as f:
f.write(html)
这样就完成了一次HTTP的请求与响应
是不是太麻烦了?
socket是TCP的封装
那么如何封装HTTP呢?
wsgi出来了
总结:客户端与服务端通过socket建立TCP连接,然后在TCP(保证数据的传输)连接上发送符合HTTP协议的文本。为了HTTP能更加简单的完成响应,于是在socket基础上,封装了wsgi。只需要实现函数
def application(environ, start_response):
start_response('200 OK', [('Content-Type', 'text/html')])
return [b'<h1>Hello, web!</h1>']
environ是HTTP请求内容,start_response是响应头
return 返回的是响应体
根据environ去响应不同的类容,这就是web应用了
为了更方便应用,在wsgi基础上,还会进行进一步封装,这便是框架