python实现web服务器(一)

import socket, os.path, threading

LEN=1024*64
HOME_PAGE='index.html'
HTML_404='404.html'
WEB_ROOT=r'C:\Users\mym\Desktop\暑期上课'

def main(port=80):
    #默认就是ipv4,tcp
    server=socket.socket()
    server.bind(('0.0.0.0',port))
    # 与操作系统有很大关系,需要操作系统支持,有时设置了,也没用
    server.listen(5)
    print('启动成功!')
    while True:
        # client就是socket对象,表示该客户的
        client,addr=server.accept()
        threading.Thread(target=handle,args=(client,addr)).start()

def handle(client,addr):
    # 读取请求头信息
    fp=client.makefile('r',encoding='utf-8')
    line=fp.readline(LEN)

    if line=='':
        return
    # 读取第一行指令
    method,url,version=line.split(' ')
    print('method:',method)
    print('url:',url)
    print('version:',version)

    headers=readheaders(fp)
    print(headers)
    # 发送数据
    if url=='/':
        url=HOME_PAGE

    # 读文件并发送,采用二进制发送,读一部分发送一部分
    if url[0]=='/':
        url=url[1:]

    filepath=os.path.join(WEB_ROOT,url)
    sendfile(client,filepath)

def readheaders(fp):
    # 读取并封装后面的头信息
    headers={}
    while True:
        line=fp.readline()
        # print(line,end='')
        if line=='\n':
            break
        pos=line.index(':')
        headers[line[:pos]]=line[pos+2:-1]


    return headers  
# 发送文件
def sendfile(client,filepath):
    if os.path.exists(filepath):
        # 发送响应头 response headers
        client.send(b'HTTP/1.1 200 OK\r\n')
    else:
        # 发送响应头 response headers
        client.send(b'HTTP/1.1 404 NOT FOUND\r\n')
        filepath=os.path.join(WEB_ROOT,HTML_404)

    # 截取访问资源的后缀,并转换小写
    suffix=filepath[filepath.rindex('.')+1:].lower()
    content_type=get_content_type(suffix)
    client.send(content_type)
    filesize=os.path.getsize(filepath)
    client.send(('Content-Length: %s\r\n'%filesize).encode('utf-8'))
    client.send(b'Server: shanghaibaolei\r\n')
    client.send(b'\r\n')
    with open(filepath,'rb') as f:
        data=f.read(LEN)
        client.sendall(data)

    client.close()
# 根据访问资源的后缀,获取content-type
def get_content_type(suffix):
    ret=None
    if suffix=='html':
        ret=b'Content-Type: text/html;charset=UTF-8\r\n'
    elif suffix=='png':
        ret=b'Content-Type: image/png\r\n'
    elif suffix=='gif':
        ret=b'Content-Type: image/gif\r\n'
    elif suffix in ['jpg','jpeg']:
        ret=b'Content-Type: image/jpeg\r\n'
    elif suffix =='css':
        ret=b'Content-Type: text/css\r\n'
    elif suffix =='js':
        ret=b'Content-Type: application/x-javascript\r\n'
    return ret

if __name__ == "__main__":
    main()

原文出处:/show_1EF3w3iqEWMn.html