[Python] Mini server

一. Web静态服务器

显示固定的页面

# -*- coding: utf-8 -*-
# Time    : 2019/2/10 18:22
# Author  : Mifen
# Email   : [email protected]
# 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   : [email protected]
# 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 = r‘html/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   : [email protected]
 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 = r‘html/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   : [email protected]
# 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 = r‘html/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   : [email protected]
# 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]

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

时间: 2024-11-09 00:44:04

[Python] Mini server的相关文章

小测几种python web server的性能

http://blog.csdn.net/raptor/article/details/8038476 因为换了nginx就不再使用mod_wsgi来跑web.py应用了,现在用的是gevent-wsgi,效果还不错.但还是想试试别的,比如传说中超级猛的meinheld什么的. 软硬件环境 硬件: 一台04年初购置的IBM X235服务器,CPU为Xeon 2.4G两颗,内存1G,100M网卡. 软件: Ubuntu Server 10.04 LTSApache 2.2.14Nginx 0.7.

带错误处理的python socket server服务范例的代码

下面的内容段是关于带错误处理的python socket server服务范例的内容,应该是对码农们有用途. import socket, traceback host = '' port = 51423 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) s.bind((host, port)) s.listen(1) whil

python http server handle json

用Python实现一个http server # python2 # coding = utf-8 from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler import json class RequestHandler(BaseHTTPRequestHandler): def _set_headers(self): self.send_response(200) self.send_header('Content-type',

python web server gateway interface (wsgi ) notes

前言: 注:如果需要得到支持批Python3.x以及包含了勘误表,附录,和说明的更新版规范,请查看PEP 3333 摘要: 这篇文档详细说明了一套在web服务器与Python web应用程序(web框架)之间的已提出的标准接口,从而方便web应用在各种web服务器之间的移植. 理论和目标 Python世界目前拥有各种各样的web应用框架,仅举几例比如 Zope, Quixote, Webware, SkunkWeb, PSO, and Twisted Web 等[1],对于新手来说面对如此多的选

Notes on PEP333 (Python Web Server Gateway Interface)

This note is about PEP3333- Python Web Server Gateway Interface. Refer to (Source: http://legacy.python.org/dev/peps/pep-3333/) for the complete description.  1. From the Application/Framwork side The application object is simply a callable object th

python - socket - server

网络上关于socket的介绍文章数不胜数.自己记录下学习的点点滴滴.以供将来复习学习使用. socket中文的翻译是套接字,总感觉词不达意.简单的理解就是ip+port形成的一个管理单元.也是程序中应用程序调用的接口. 在这里我们就介绍如何启动tcp 的server. tcp连接中server部分,启动一个ip和port口,在这个port口监听,当收到client发来的请求,用一个新的端口port2同client建立连接. socket启动监听的过程就是: 创建socket bind端口 开始监

example of Python http server

from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler print "hello " class TestHTTPHandle(BaseHTTPRequestHandler): def do_GET(self): print self.client_address print self.command buf = 'It works' self.protocal_version = "HTTP/1.1&quo

Mac Mini Server安装Centos6.5

最近单位有这样的需求,因为mac mini好看又稳定,入手了几台,但是在部署环境以及软件调试时,mac os是真心不好用呀……所以计划将OS整个删除,安装纯净的Centos6.5.网上扒了一堆帖子,自己也作了如下总结,用以知识储备. 1.制作U盘启动: 可以按照windows下制作U盘启动,网上方法有很多,我是把U盘插入mac mini,运行dd命令制作的,参考:http://www.ubuntu.com/download/desktop/create-a-usb-stick-on-mac-os

【转】由Microsoft python language Server 下载特别慢引发的问题

在求pycharm的激活码无果后,果断投入vscode的阵营 但是无奈之前vscode编写Python代码,智能提示实在太慢,网上搜寻各种解决办法,今天终于找到,亲测可行 看来是 Visual Studio IntelliCode 的锅,解决办法: 1.文件--首选项--设置,搜索jedi ,将jedi enable勾选,下面的解释意思大概就是用这个代替微软的后台分析 2.重启vscode,右下角会提示 Visual Studio IntelliCode 无法加载,然后点到插件设置,禁用或者直接