01 web框架雏形-socket套接字

web框架雏形

之前总结过这两个模块的应用,web框架雏形就是socket套接字。

socket套接字链接:https://www.cnblogs.com/znyyy/p/10144936.html

flask模块链接:https://www.cnblogs.com/znyyy/p/10072938.html

web框架就是实现,用户通过浏览器发送请求到服务器,服务器执行代码处理数据,返回数据给浏览器,浏览器拿到数据进行解析,显示给用户看。就是这样一个过程,比如下面的例子,当用户在浏览器输入http://127.0.0.1:8081/ 浏览器就会显示如下图所示:

 

代码:

 1 import socket,subprocess,struct,json
 2 
 3 
 4 '''
 5 地址簇:
 6 socket.AF_INET:典型的TCP/IP四层模型的通信过程,发送方、接收方依赖IP:Port来标识,即将本地的socket绑定到对应的IP端口上;
 7 发送数据时,指定对方的IP端口,经过Internet,可以根据此IP端口最终找到接收方;接收数据时,可以从数据包中获取到发送方的IP端口。
 8 socket.AF_UNIX:典型的本地IPC,类似于管道,依赖路径名标识发送方和接收方。即发送数据时,指定接收方绑定的路径名,
 9 操作系统根据该路径名可以直接找到对应的接收方,并将原始数据直接拷贝到接收方的内核缓冲区中,并上报给接收方进程进行处理。
10 同样的接收方可以从收到的数据包中获取到发送方的路径名,并通过此路径名向其发送数据.(可实现进程间的通讯)
11 类型:
12 socket.SOCK_STREAM:流式socket , for TCP
13 socket.SOCK_DGRAM: 数据报式socket , for UDP
14 socket.SOCK_RAW:   原始套接字,普通的套接字无法处理ICMP、IGMP等网络报文,而SOCK_RAW可以;
15 SOCK_RAW也可以处理特殊的IPv4报文;此外,利用原始套接字,可以通过IP_HDRINCL套接字选项由用户构造IP头。
16 '''
17 ip_port= ("127.0.0.1",8081)
18 max_connect = 1  # 最对只接收5个连接,超过时直接拒绝
19 
20 # 实例化socket套接字对象,指定地址簇为socket.AF_INET;类型为socket.SOCK_STREAM 流式socket , for TCP
21 server_socket = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM)
22 # 端口复用,当程序重启时端口还是被占用的,加上这个可忽略端口冲突报错
23 server_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
24 server_socket.bind(ip_port)  # 绑定本机ip+port
25 server_socket.listen(max_connect)  # 开始TCP监听,5代表在允许有一个连接排队,更多的新连接连进来时就会被拒绝
26 print("starting....")
27 while True: # 循环生成连接对象,当前连接断开马上进入下一次等待,知道有连接
28     try:  # 当客户端暴力断开连接时,windows下会报错,所以用try防止报错导致程序奔溃
29         conn,client_addr = server_socket.accept()  # #阻塞直到有连接为止,有了一个新连接进来后,就会为这个请求生成一个连接对象
30         while True: # 循环和客户端交互,收、发信息
31             rec = conn.recv(1024)  # 最多接收1024个字节的数据
32             if not rec:break  # 当客户端暴力断开连接时,linux下会进入死循环接收数据为空,所以当接收数据为空的时候跳出循环
33             # 发送数据给客户端,必须要发送这个,浏览器才可以解析
34             conn.send("HTTP/1.1 200 OK\r\nstatus: 200\r\nContent-Type:text/html\r\n\r\n".encode("utf8"))
35             conn.send("<h1>Hello, World!</h1><img src=''>".encode("utf8"))
36         conn.close()  # 关闭连接套接字
37     except Exception as e:
38         print(e)
39 
40 server_socket.close()  # 关闭套接字

 

返回html页面,浏览器解析结果如下

 

代码

# -*- coding: utf-8 -*-
# @Time    : 2019/7/8 8:37
# @Author  : Xiao

import socket

ip_port= ("127.0.0.1",8081)
max_connect = 1  # 最对只接收5个连接,超过时直接拒绝

# 实例化socket套接字对象,指定地址簇为socket.AF_INET;类型为socket.SOCK_STREAM 流式socket , for TCP
server_socket = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM)
# 端口复用,当程序重启时端口还是被占用的,加上这个可忽略端口冲突报错
server_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
server_socket.bind(ip_port)  # 绑定本机ip+port
server_socket.listen(max_connect)  # 开始TCP监听,5代表在允许有一个连接排队,更多的新连接连进来时就会被拒绝
print("starting....")
while True: # 循环生成连接对象,当前连接断开马上进入下一次等待,知道有连接
    try:  # 当客户端暴力断开连接时,windows下会报错,所以用try防止报错导致程序奔溃
        conn,client_addr = server_socket.accept()  # #阻塞直到有连接为止,有了一个新连接进来后,就会为这个请求生成一个连接对象
        rec = conn.recv(1024)  # 最多接收1024个字节的数据
        if not rec:break  # 当客户端暴力断开连接时,linux下会进入死循环接收数据为空,所以当接收数据为空的时候跳出循环
        # 注意一定要以rb形式打开,因为http网络传输的时候只能传输bytes字节,如果不是rb,需要encode转一下才可以
        with open('index.html', 'rb') as f:
            data = f.read()
        # 发送数据给客户端,必须要发送这个,浏览器才可以解析
        conn.send(b"HTTP/1.1 200 OK\r\nstatus: 200\r\nContent-Type:text/html\r\n\r\n%s"%data)
        conn.close()  # 关闭连接套接字
    except Exception as e:
        print(e)

 

posted @ 2019-07-08 08:24  毛斯钢  阅读(186)  评论(0编辑  收藏  举报