因为网络间通信是基于TCP协议传输数据的,而服务器与浏览器之间通信是基于HTTP协议的,那么下面基于python实现一个tcp服务器,浏览器可以基于http协议进行发送请求和解析。展示浏览器返回一个固定页面和HTML页面案例。
1.服务器只能返回固定页面给请求者
import socket def handle_client(client_socket): "为一个客户端进行服务" recv_data =
client_socket.recv(1024).decode("utf-8") request_header_lines =
recv_data.splitlines() for line in request_header_lines: print(line) # 组织相应
头信息(header) response_headers = "HTTP/1.1 200 OK\r\n" # 200表示找到这个资源
response_headers += "\r\n" # 用一个空的行与body进行隔开 # 组织 内容(body) response_body =
"hello world" response = response_headers + response_body
client_socket.send(response.encode("utf-8")) client_socket.close() def main():
"作为程序的主控制入口" server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 设置当服务器先close 即服务器端4次挥手之后资源能够立即释放,这样就保证了,下次运行程序时 可以立即绑定7788端口
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_socket.bind(("", 7788)) server_socket.listen(128) while True:
client_socket, client_addr = server_socket.accept()
handle_client(client_socket) if __name__ == "__main__": main()
使用“网路调试助手"作为TCP 客户端发送请求给服务器,服务器将固定返回基于http协议格式的hello,world给所有的请求者。
使用浏览器基于HTTP协议访问该服务器如下,服务器将固定返回基于http协议格式的hello,world给所有的请求者。这里因为浏览器可以解析http协议的格式文件,所以可以通过网页的形式展示出来hello,world。当然如果浏览器返回一个完整的网页,那么同样浏览器也可以解析整个网页,这就是我们日常使用的服务器与浏览器基于http协议的通信啦。
2.服务器返回一个网页页面给请求者
浏览器通过http协议请求该TCP服务器,该服务器返回一个网页页面给浏览器,浏览器解析以后显示到前端。
import socket def service_client(new_socket): """为这个客户端返回数据""" # 1.
接收浏览器发送过来的请求 ,即http请求 # GET / HTTP/1.1 # ..... request = new_socket.recv(1024)
print(">>>" * 50) print(request) # 2. 返回http格式的数据,给浏览器 # 2.1
准备发送给浏览器的数据---header response = "HTTP/1.1 200 OK\r\n" response += "\r\n" # 2.2
准备发送给浏览器的数据---boy # response += "hahahhah" f = open("./html/index.html", "rb")
#读取的这个文件是我们提前放在程序当前目录下的,用来测试的文件。 html_content = f.read() f.close() # 将response
header发送给浏览器 new_socket.send(response.encode("utf-8")) # 将response body发送给浏览器
new_socket.send(html_content) #注意这里send的数据没有encode,文件open的方式就是rb,二进制格式 # 关闭套接
new_socket.close() def main(): """用来完成整体的控制""" # 1. 创建套接字 tcp_server_socket =
socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 设置当服务器先close
即服务器端4次挥手之后资源能够立即释放,这样就保证了,下次运行程序时 可以立即绑定7890端口
tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # 2. 绑定
tcp_server_socket.bind(("", 7890)) # 3. 变为监听套接字 tcp_server_socket.listen(128)
while True: # 4. 等待新客户端的链接 new_socket, client_addr = tcp_server_socket.accept()
# 5. 为这个客户端服务 service_client(new_socket) # 关闭监听套接字 tcp_server_socket.close() if
__name__ == "__main__": main()
使用浏览器访问服务器,因为这里我定义的是服务器固定返回一个网页(这个网页使我们提前放在服务器上的。),所以只要你访问的是这个服务器,这个端口
,所有的返回都是一样。 所以,你访问的网址,可以任意定义,都不会影响这个访问结果,比如http://127.0.0.1:7890/dfsdf/aaaa
<http://127.0.0.1:7890/dfsdf/aaaa>,http://127.0.0.1:7890/
<http://127.0.0.1:7890/dfsdf/aaaa>aaa/index 等结果都是一样的。
因为对于客户端的访问链接(文件内容)服务器端不去进行解析,而是无论你要啥我都给你这个结果。
如下服务器端打印显示了浏览器的get请求,但是注意,实际我们访问一次,但是服务器显示浏览器发送了多次get请求,这是为什么呢?
尖叫提示:当浏览器读取到index首页的HTML源码后,它会解析HTML,显示页面,然后,根据HTML里面的各种链接,再发送HTTP请求给服务器,拿到相应的图片、视频、Flash、JavaScript脚本、CSS等各种资源,最终显示出一个完整的页面。所以我们在下面能看到很多额外的HTTP请求。
D:\software\python3\python.exe
D:/pythoyworkspace/file_demo/Class_Demo/pachong/urllib_Request_Post.py
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
b'GET / HTTP/1.1\r\nHost: 127.0.0.1:7890\r\nConnection:
keep-alive\r\nCache-Control: max-age=0\r\nUpgrade-Insecure-Requests:
1\r\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36
(KHTML, like Gecko) Chrome/75.0.3770.80 Safari/537.36\r\nAccept:
text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3\r\nAccept-Encoding:
gzip, deflate, br\r\nAccept-Language: zh-CN,zh;q=0.9\r\n\r\n'
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
b'GET /classic.css HTTP/1.1\r\nHost: 127.0.0.1:7890\r\nConnection:
keep-alive\r\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.80
Safari/537.36\r\nAccept: text/css,*/*;q=0.1\r\nReferer:
http://127.0.0.1:7890/\r\nAccept-Encoding: gzip, deflate,
br\r\nAccept-Language: zh-CN,zh;q=0.9\r\n\r\n'
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
b'GET /images/qt-logo.png HTTP/1.1\r\nHost: 127.0.0.1:7890\r\nConnection:
keep-alive\r\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.80
Safari/537.36\r\nAccept: image/webp,image/apng,image/*,*/*;q=0.8\r\nReferer:
http://127.0.0.1:7890/\r\nAccept-Encoding: gzip, deflate,
br\r\nAccept-Language: zh-CN,zh;q=0.9\r\n\r\n'
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
b'GET /images/trolltech-logo.png HTTP/1.1\r\nHost:
127.0.0.1:7890\r\nConnection: keep-alive\r\nUser-Agent: Mozilla/5.0 (Windows NT
10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.80
Safari/537.36\r\nAccept: image/webp,image/apng,image/*,*/*;q=0.8\r\nReferer:
http://127.0.0.1:7890/\r\nAccept-Encoding: gzip, deflate,
br\r\nAccept-Language: zh-CN,zh;q=0.9\r\n\r\n'
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
b'GET /favicon.ico HTTP/1.1\r\nHost: 127.0.0.1:7890\r\nConnection:
keep-alive\r\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.80
Safari/537.36\r\nAccept: image/webp,image/apng,image/*,*/*;q=0.8\r\nReferer:
http://127.0.0.1:7890/\r\nAccept-Encoding: gzip, deflate,
br\r\nAccept-Language: zh-CN,zh;q=0.9\r\n\r\n'
尖叫提示:尽管按理说客户端解析HTML后,根会据HTML里的链接再发送HTTP请求给服务器,拿到相应的图片、视频、Flash、JavaScript脚本、CSS等各种资源,最终显示出一个完整的页面。但是我们看到下面实际返回的网页的左上角和右上角有图标(图片)是缺失的,没有显示出来,这是为什么呢?
这是因为尽管客户端给我们的服务器发送了这些资源请求,但是我们的服务器并没有解析这些请求,按请求的文件内容返回给客户端浏览器,所以要想让客户端实现拿到相应的图片、视频、Flash、JavaScript脚本、CSS等各种资源,最终显示出一个完整的页面,我们需要再定义服务器解析客户端请求内容的解析函数,具体参考后面系列2博客。
热门工具 换一换