python实现外部静态服务器,浏览器通过HTTP与之通信1

    因为网络间通信是基于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/aaaahttp://127.0.0.1:7890/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博客。

发布了248 篇原创文章 · 获赞 1600 · 访问量 267万+

猜你喜欢

转载自blog.csdn.net/qq_26442553/article/details/95033592