博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
面向对象封装的web服务器
阅读量:5996 次
发布时间:2019-06-20

本文共 6352 字,大约阅读时间需要 21 分钟。

import socketimport reimport osimport sys# 由于前面太繁琐,可以用类封装一下,也可以分几个模块class HttpServer(object):    def __init__(self,port):        # 1、服务器创建负责监听的socket        self.socket_watch = socket.socket(socket.AF_INET, socket.SOCK_STREAM)        # 2、设置地址重用        self.socket_watch.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)        # 3、绑定监听的端口        self.socket_watch.bind(('', port))        # 4、设置监听队列        self.socket_watch.listen(128)    def handle_client(self,socket_con):        """         接收来自客户端的请求,并接收请求报文,解析,返回        """        # 1、服务器接收客户端的请求报文        request = socket_con.recv(4096).decode()        # 2、截取请求报文,获取请求行        request_lines = request.split("\r\n")        # 3、获取请求行        request_line = request_lines[0]        # GET /a/ab/c.html HTTP/1.1        # 通过正则表达式 匹配出请求行中请求资源路径        res = re.match(r"\w+\s+(\S+)",request_line)        # 获取资源路径        path = res.group(1)        # 将资源路径和我的web文件夹的绝对路径拼接(自己填写)        path ="# 本地绝对路径" + path        # 在判断是文件还是文件夹之前,首先要判断你这个路径在服务器中是否存在        if not os.path.exists(path):            response_line = 'HTTP/1.1 404 Not Found\r\n'            response_head = 'Server:skylark 2.0\r\n'            response_head += 'Content-type:text/html;charset=utf-8\r\n'            response_body = '你请求'+ path +'不存在'            response = response_line + response_head + '\r\n' +response_body            socket_con.send(response.encode())            socket_con.close()            return        else:            # 判断用户请求的是文件还是文件夹             if os.path.isfile(path):                 # 如果文件存在 读取页面数据,然后返回                response_line = "HTTP/1.1 200 OK\r\n"                response_head = "Server:skylark 2.0\r\n"                # 注意请求图片需要使用"rb"的方式进行读取                file = open(path,"rb")                # response_body 是二进制所以不用再次编码                response_body = file.read()                response = response_line.encode() + response_head.encode() +"\r\n".encode() +response_body                socket_con.send(response)                socket_con.close()                return             else:                if path.endswith("/"):                    # 例如 www.baidu.com/images                    # 用户请求的文件夹                    # 1、判断该文件夹下是否有默认的文件,如果有,则返回,如果没有                    # index.html default.html                    default_document = False                    # 如果允许你访问我目录下的默认文档                    if default_document:                        # 判断用户访问的文件夹下是否有index.html 或者 default.html                        if os.path.exists(path + '/index.html'):                            response_line = 'HTTP/1.1 200 OK\r\n'                            response_head = 'Server:skylark 2.0\r\n'                            file = open(path+'/index.html', 'rb')                            response_body = file.read()                            response = response_line.encode() + response_head.encode() +'\r\n'.encode()+response_body                            socket_con.send(response)                            socket_con.close()                            return                        elif os.path.exists(path + '/default.html'):                            response_line = 'HTTP/1.1 200 OK\r\n'                            response_head = 'Server:skylark 2.0\r\n'                            file = open(path + '/default.html', 'rb')                            response_body = file.read()                            response = response_line.encode() + response_head.encode() + '\r\n'.encode() + response_body                            socket_con.send(response)                            socket_con.close()                            return                        else:                            # 访问的目录下,既没有index.html 也没有default.html                            response_line = 'HTTP/1.1 404 Not Found\r\n'                            response_head = 'Server:skylark 2.0\r\n'                            response_head += 'Content-Type:text/html;charset=utf-8\r\n'                            response_body = 'index.html 或者 default.html 不存在'                            response = response_line +response_head +'\r\n' +response_body                            socket_con.send(response.encode())                            socket_con.close()                        # 2、判断服务器是否开启了目录浏览                    else:                        # 判断你是否开启了目录浏览                        dir_browsing = True                        if dir_browsing:                            # 把用户请求的文件夹中所有的文件和文件夹以目录的形式返回到页面中                            # 获取用户请求的文件夹                            list_names = os.listdir(path)                            response_line = 'HTTP/1.1 200 OK\r\n'                            response_head = 'Server:skylark 2.0\r\n'                            # 动态的拼接页面,将目录中的文件或者文件夹的名称以HTML页面的方式返回给浏览器                            response_body = '
    ' for item in list_names: response_body +="
  • "+item+"
  • " response_body+='
' response =response_line + response_head +'\r\n' +response_body socket_con.send(response.encode()) socket_con.close() return else: # 用户请求的路径没有斜线 # 重定向到+斜线的目录下 response_line = 'HTTP/1.1 302 Found\r\n' response_head = 'Server:skylark 2.0\r\n' response_body = 'redirect'+ path +'/' response = response_line +response_head +'\r\n' +response_body socket_con.send(response.encode()) socket_con.close() def run_server(self): # 5、通过循环,不停的接收来自客户端的连接请求 while True: socket_con, con_adds = self.socket_watch.accept() # 注意将con_adds转成字符串 print('客户端:%s连接成功!!!' % str(con_adds)) # 接收来自客户端的请求,并接收请求报文,解析,返回 self.handle_client(socket_con)def main(): # sys.argv方法的用法如下: # 在终端输入 python3 面向对象封装的web服务器.py 8888 # 在使用解释器执行任意py文件的时候,可以传入不止一个参数,会以字符串的形式用列表保存起来 # 但是列表的第一个参数[0]位是它自己。所以传入的参数是从[1]第二位开始的 # 所以在上面输入8888以后,调取这个列表的[1]下标就会传入这个8888作为进到下面的代码 # 再转换一下类型为int就相当于用户指定端口了 port = int(sys.argv[1]) http_server = HttpServer(port) http_server.run_server()if __name__ == '__main__': main()

  

转载于:https://www.cnblogs.com/wf-skylark/p/9027154.html

你可能感兴趣的文章
centos使用yum安装软件的时候出现了undefined symbol: CRYPTO_set_locking_callback
查看>>
对springMVC的简单理解
查看>>
android studio下生成jni头文件
查看>>
最简单的Android教程之自定义控件
查看>>
虚拟 router 原理分析- 每天5分钟玩转 OpenStack(101)
查看>>
使用linux的shell脚本实现在当前行重复动态显示时间等字符串信息(不另起新行)...
查看>>
myeclipse开发代码颜色搭配保护视力
查看>>
iOS开发-数据存储NSCoder
查看>>
SQL Server 存储过程【转】
查看>>
localstorage和sessionstorage上手使用记录
查看>>
荣耀手机缅甸仰光店开业,只有我觉得缅甸美女比较多吗?
查看>>
费德勒三盘击败西里奇摘大满贯第19冠
查看>>
融合数据库技术,降低开源MySQL使用成本实践
查看>>
IDC:全球以太网交换机和路由器市场整体看涨
查看>>
英国零售商:“无协议脱欧”恐让超市空荡荡
查看>>
致 CODING 用户的元宵问候
查看>>
看Zepto如何实现增删改查DOM
查看>>
《从零构建前后分离的web项目》:前端1.0 终 - 前端性能优化 (多图预警)
查看>>
什么都不做就能赚钱?Airbnb靠什么牛逼的技术赚全世界人的钱?
查看>>
读Zepto源码之操作DOM
查看>>