码迷,mamicode.com
首页 > 编程语言 > 详细

[Python] Mini server

时间:2019-06-02 01:37:38      阅读:154      评论:0      收藏:0      [点我收藏+]

标签:art   star   访问   headers   运行   服务器端   lines   使用   inux   

一. Web静态服务器

显示固定的页面

# -*- coding: utf-8 -*-
# Time    : 2019/2/10 18:22
# Author  : Mifen
# Email   : 2952277346@qq.com
# Software: PyCharm

import socket


def service_client(conn):
    ‘‘‘接收客户端发送的数据‘‘‘
    request = conn.recv(1024)
    print(request)
    # 返回客户端请求的数据
    response = HTTP/1.1 200 OK\r\n
    response += \r\n
    response += 你好雇佣兵
    conn.send(response.encode(utf-8))
    conn.close()


def main():
    ‘‘‘ 实现主要的功能控制‘‘‘
    # 1.创建socket
    serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 设置当服务器先close 即服务器端4次挥手之后资源能够立即释放,这样就保证了,下次运行程序时 可以立即绑定8080端口
    serversocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    # 2.绑定端口
    serversocket.bind((‘‘, 8080))
    # 3.监听
    serversocket.listen(128)
    while True:
        # 4.等待连接
        conn, addr = serversocket.accept()
        # 5.与客户端通信
        service_client(conn)


if __name__ == __main__:
    main()

显示需要的页面

# -*- coding: utf-8 -*-
# Time    : 2019/2/10 19:52
# Author  : Mifen
# Email   : 2952277346@qq.com
# Software: PyCharm
import socket
import re


def handle_client(client_socket):
    "为一个客户端进行服务"
    recv_data = client_socket.recv(1024).decode(utf-8, errors="ignore")
    request_header_lines = recv_data.splitlines()
    for line in request_header_lines:
        print(line)

    http_request_line = request_header_lines[0]
    get_file_name = re.match("[^/]+(/[^ ]*)", http_request_line).group(1)
    print("file name is ===>%s" % get_file_name)  # for test

    # 如果没有指定访问哪个页面。例如index.html
    # GET / HTTP/1.1
    if get_file_name == "/":
        get_file_name = rhtml/index.html
    else:
        get_file_name = html + get_file_name

    print("file name is ===2>%s" % get_file_name)  # for test

    try:
        f = open(get_file_name, "rb")
    except IOError:
        # 404表示没有这个页面
        response_headers = "HTTP/1.1 404 not found\r\n"
        response_headers += "\r\n"
        response_body = "404 not found"
    else:
        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(utf-8))
        # 再发送body
        client_socket.send(response_body)
        client_socket.close()


def main():
    "作为程序的主控制入口"
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    server_socket.bind(("127.0.0.1", 8080))
    server_socket.listen(128)
    while True:
        client_socket, clien_cAddr = server_socket.accept()
        handle_client(client_socket)


# 这里配置服务器
DOCUMENTS_ROOT = "./html"

if __name__ == "__main__":
    main()

多进程、线程实现http服务器

 1 # -*- coding: utf-8 -*-
 2 # Time    : 2019/2/11 19:52
 3 # Author  : Mifen
 4 # Email   : 2952277346@qq.com
 5 # Software: PyCharm
 6 
 7 
 8 import socket
 9 import re
10 import threading
11 import multiprocessing
12 
13 
14 def handle_client(client_socket):
15     "为一个客户端进行服务"
16     recv_data = client_socket.recv(1024).decode(utf-8, errors="ignore")
17     request_header_lines = recv_data.splitlines()
18     for line in request_header_lines:
19         print(line)
20 
21     http_request_line = request_header_lines[0]
22     get_file_name = re.match("[^/]+(/[^ ]*)", http_request_line).group(1)
23     print("file name is ===>%s" % get_file_name)  # for test
24 
25     # 如果没有指定访问哪个页面。例如index.html
26     # GET / HTTP/1.1
27     if get_file_name == "/":
28         get_file_name = rhtml/index.html
29     else:
30         get_file_name = html + get_file_name
31 
32     print("file name is ===2>%s" % get_file_name)  # for test
33 
34     try:
35         f = open(get_file_name, "rb")
36     except IOError:
37         # 404表示没有这个页面
38         response_headers = "HTTP/1.1 404 not found\r\n"
39         response_headers += "\r\n"
40         response_body = "====sorry ,file not found===="
41     else:
42         response_headers = "HTTP/1.1 200 OK\r\n"
43         response_headers += "\r\n"
44         response_body = f.read()
45         f.close()
46     finally:
47         # 因为头信息在组织的时候,是按照字符串组织的,不能与以二进制打开文件读取的数据合并,因此分开发送
48         # 先发送response的头信息
49         client_socket.send(response_headers.encode(utf-8))
50         # 再发送body
51         client_socket.send(response_body)
52         client_socket.close()
53 
54 
55 def main():
56     "作为程序的主控制入口"
57     server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
58     server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
59     server_socket.bind(("192.168.43.227", 8080))
60     server_socket.listen(128)
61     while True:
62         client_socket, clien_cAddr = server_socket.accept()
63         t = threading.Thread(target=handle_client, args=(client_socket,))
64         t.start()
65         # 如果用多进程实现多任务,因为子进程已经复制了父进程的套接字等资源,所以父进程调用close不会将他们对应的这个链接关闭的
66         # client_socket.close()
67 
68 
69 # 这里配置服务器
70 DOCUMENTS_ROOT = "./html"
71 
72 if __name__ == "__main__":
73     main()

二. Web并发服务器

gevent实现http服务器

# -*- coding: utf-8 -*-
# Time    : 2019/2/11 20:06
# Author  : Mifen
# Email   : 2952277346@qq.com
# Software: PyCharm


import socket
import re
import gevent
from gevent import monkey
monkey.patch_all()

def handle_client(client_socket):
    "为一个客户端进行服务"
    recv_data = client_socket.recv(1024).decode(utf-8, errors="ignore")
    request_header_lines = recv_data.splitlines()
    for line in request_header_lines:
        print(line)

    http_request_line = request_header_lines[0]
    get_file_name = re.match("[^/]+(/[^ ]*)", http_request_line).group(1)
    print("file name is ===>%s" % get_file_name)  # for test

    # 如果没有指定访问哪个页面。例如index.html
    # GET / HTTP/1.1
    if get_file_name == "/":
        get_file_name = rhtml/index.html
    else:
        get_file_name = html + get_file_name

    print("file name is ===2>%s" % get_file_name) #for test

    try:
        f = open(get_file_name, "rb")
    except IOError:
        # 404表示没有这个页面
        response_headers = "HTTP/1.1 404 not found\r\n"
        response_headers += "\r\n"
        response_body = "====sorry ,file not found===="
    else:
        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(utf-8))
        # 再发送body
        client_socket.send(response_body)
        client_socket.close()


def main():
    "作为程序的主控制入口"
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    server_socket.bind(("192.168.43.227", 8080))
    server_socket.listen(128)
    while True:
        client_socket, clien_cAddr = server_socket.accept()
        gevent.spawn(handle_client,client_socket)

#这里配置服务器
DOCUMENTS_ROOT = "./html"

if __name__ == "__main__":
    main()

epoll版的http服务器

# -*- coding: utf-8 -*-
# Time    : 2019/2/11 22:01
# Author  : Mifen
# Email   : 2952277346@qq.com
# Software: PyCharm

import socket
import select

# 创建套接字
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 设置可以重复使用绑定的信息
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

# 绑定本机信息
s.bind(("", 7788))

# 变为被动
s.listen(10)
# 创建一个epoll对象
epoll = select.epoll()  # epoll只能再Linux下运行

# 测试,用来打印套接字对应的文件描述符
# print(s.fileno())
# print(select.EPOLLIN|select.EPOLLET)

# 注册事件到epoll中
# epoll.register(fd[, eventmask])
# 注意,如果fd已经注册过,则会发生异常
# 将创建的套接字添加到epoll的事件监听中
epoll.register(s.fileno(), select.EPOLLIN | select.EPOLLET)

connections = {}
addresses = {}

# 循环等待客户端的到来或者对方发送数据
while True:

    # epoll 进行 fd 扫描的地方 -- 未指定超时时间则为阻塞等待
    epoll_list = epoll.poll()

    # 对事件进行判断
    for fd, events in epoll_list:

        # print fd
        # print events

        # 如果是socket创建的套接字被激活
        if fd == s.fileno():
            new_socket, new_addr = s.accept()

            print(有新的客户端到来%s % str(new_addr))

            # 将 conn 和 addr 信息分别保存起来
            connections[new_socket.fileno()] = new_socket
            addresses[new_socket.fileno()] = new_addr

            # 向 epoll 中注册 新socket 的 可读 事件
            epoll.register(new_socket.fileno(), select.EPOLLIN | select.EPOLLET)

        # 如果是客户端发送数据
        elif events == select.EPOLLIN:
            # 从激活 fd 上接收
            recvData = connections[fd].recv(1024).decode("utf-8")

            if recvData:
                print(recv:%s % recvData)
            else:
                # 从 epoll 中移除该 连接 fd
                epoll.unregister(fd)

                # server 侧主动关闭该 连接 fd
                connections[fd].close()
                print("%s---offline---" % str(addresses[fd]))
                del connections[fd]
                del addresses[fd]

 

[Python] Mini server

标签:art   star   访问   headers   运行   服务器端   lines   使用   inux   

原文地址:https://www.cnblogs.com/Mifen2952277346/p/10924253.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!