因为网络间通信是基于TCP协议传输数据的,而服务器与浏览器之间通信是基于HTTP协议的,那么下面基于python实现一个tcp服务器,浏览器可以基于http协议进行发送请求和解析。浏览器展示返回的一个标准的HTML网页,此外实现服务器解析客户端多次请求并且返回请求结果。即:客户端根据HTML里面的各种链接,再发送HTTP请求给服务器,拿到相应的图片、视频、Flash、JavaScript脚本、CSS等各种资源,最终显示出一个完整的页面。

1.代码实现web服务器,实现解析用户请求并且返回对应结果
#coding=utf-8 import socket import re def handle_client(client_socket):
"为一个客户端进行服务" recv_data = client_socket.recv(1024).decode('gbk',
errors="ignore") #报错忽略 ''' 注意尽管客户端可以根据返回的HTML里的链接发送二次请求,但是要想正确返回请求内容,需要服务器能够解析
这些请求内容,找到这些内容读取后send给客户端。所以下面要做的就是解析客户端的请求如下格式: 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' ''' request_header_lines =
recv_data.splitlines() #1.将服务器接收的数据按HTTP格式进行切分,模式分割符就是\r\n for line in
request_header_lines: #打印是为了测试使用 print(line) http_request_line =
request_header_lines[0] #2.获取请求数据的第一行,比如:GET /images/qt-logo.png HTTP/1.1
get_file_name = re.match("[^/]+(/[^ ]*)", http_request_line).group(1)
#3.获取客户端请求的文件名images/qt-logo.png print("file name is ===>%s" % get_file_name) #
for test # 如果没有指定访问哪个页面。例如index.html # GET / HTTP/1.1 if get_file_name == "/":
get_file_name = DOCUMENTS_ROOT + "/index.html" else: get_file_name =
DOCUMENTS_ROOT + get_file_name print("file name is ===2>%s" % get_file_name)
#for test try: f = open(get_file_name, "rb") except IOError: #如果没有该文件,则返回404
not found # 404表示没有这个页面 response_headers = "HTTP/1.1 404 not found\r\n"
response_headers += "\r\n" response_body = "====sorry ,file not found===="
else: #注意这里else的使用,找到了该文件返回200 OK response_headers = "HTTP/1.1 200 OK\r\n"
response_headers += "\r\n" response_body = f.read()
#读取用户请求的文件,注意这里如果文件很大,可以循环读取 f.close() finally:# 在这里将读取的文件发送给客户端。 #
因为头信息在组织的时候,是按照字符串组织的,不能与以二进制打开文件读取的数据合并,因此分开发送 # 先发送response的头信息
client_socket.send(response_headers.encode('gbk')) #注意如果在linux上测试的话,改成utf-8 #
再发送body client_socket.send(response_body) 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, clien_cAddr = server_socket.accept()
handle_client(client_socket) #这里配置服务器 DOCUMENTS_ROOT = "./html"
#因为文件都放在当前路径下的html文件夹里,所以这里定义一个固定路径,存放的是提前写好的网页文件。 if __name__ == "__main__":
main()
2.测试展示与分析

     
 启动上面程序,打开web浏览器,访问该服务器。注意,之前我们服务器是固定返回一个页面给浏览器,不去对请求的数据进行解析处理,所以192.168.1.1:7788后面跟任何字符串都行,都不会报错,现在则不行,服务器会对浏览器的请求进行解析,如下因为找不到/aaaa/bbbb/ccc而报错,404
NOT FOUND

2.1错误访问地址



  2.2.正常向服务器发送请求

     所以这个时候我们就需要按服务器上的正常部署是文件去访问了.比如我们在服务器上配置默认的路径就是index.html,所以我们直接用浏览器访问
http://192.168.1.1:7788/index.html <http://192.168.1.1:7788/index.html> 或者
http://192.168.1.1:7788 <http://192.168.1.1:7788/index.html>结果都是一样,
如下,注意下面网页的图片已经加载正常了。实现了客户端根据HTML里面的各种链接,再发送HTTP请求给服务器,拿到相应的图片、视频、Flash、JavaScript脚本、CSS等各种资源,最终显示出一个完整的页面

2.3服务器内部打印的浏览器请求与解析后的结果如下: 

  可以看出虽然请求了一次,但是浏览器因为网页内嵌的url,随后发送了多次请求,并且都得到了正确响应。
GET / HTTP/1.1 Host: 192.168.1.1:7788 Connection: keep-alive Cache-Control:
max-age=0 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT
10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.80
Safari/537.36 Accept:
text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9 file name is
===>/ file name is ===2>./html/index.html GET /classic.css HTTP/1.1 Host:
192.168.1.1:7788 Connection: keep-alive User-Agent: Mozilla/5.0 (Windows NT
10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.80
Safari/537.36 Accept: text/css,*/*;q=0.1 Referer: http://192.168.1.1:7788/
Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9 file name is
===>/classic.css file name is ===2>./html/classic.css GET /images/qt-logo.png
HTTP/1.1 Host: 192.168.1.1:7788 Connection: keep-alive User-Agent: Mozilla/5.0
(Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)
Chrome/75.0.3770.80 Safari/537.36 Accept:
image/webp,image/apng,image/*,*/*;q=0.8 Referer: http://192.168.1.1:7788/
Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9 file name is
===>/images/qt-logo.png file name is ===2>./html/images/qt-logo.png GET
/images/trolltech-logo.png HTTP/1.1 Host: 192.168.1.1:7788 Connection:
keep-alive User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.80 Safari/537.36
Accept: image/webp,image/apng,image/*,*/*;q=0.8 Referer:
http://192.168.1.1:7788/ Accept-Encoding: gzip, deflate Accept-Language:
zh-CN,zh;q=0.9 file name is ===>/images/trolltech-logo.png file name is
===2>./html/images/trolltech-logo.png
 

友情链接
ioDraw流程图
API参考文档
OK工具箱
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:ixiaoyang8@qq.com
QQ群:637538335
关注微信