多线程HTTP服务器

该代码在原有基础上利用多线程实现了多客户端浏览器同时操作的功能,对请求的类型进行分析,用不同的处理方法进行处理

from socket import *

from threading import Thread
import time

ADDR = ('0.0.0.0',8000)
#存放静态网页的目录
STATIC_DIR = './static'

#httpserver类封装服务器功能
class HTTPServer(object):
    def __init__(self,addr):
        #套接字创建
        self.sockfd = socket()
        self.sockfd.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)
        self.sockfd.bind(addr)
        self.sockfd.listen(5)
        #为对象添加属性
        self.name = 'HttpServer'
        self.port = 8000
        self.address = addr
    
    #监听客户端的连接请求,循环创建新的线程处理
    def serve_forever(self):
        print("listen to port 8000")
        while True:
            connfd,clientAddr = self.sockfd.accept()
            #创建新的线程处理具体请求
            clientThread = Thread(target = self.handleRequest,\
                args = (connfd,))

            clientThread.setDaemon(True)
            clientThread.start()

    def handleRequest(self,connfd):
        #接收客户端请求
        request = connfd.recv(1024).decode()
        requestHeadlers = request.splitlines()
        #请求行
        print(connfd.getpeername,":",requestHeadlers[0])
        getRequest = requestHeadlers[0].split(' ')[1]
        if getRequest[-3:] != '.py':
            if getRequest = '/':
                getFilename = STATIC_DIR +"/index.html"
            else:
                getFilename = STATIC_DIR + getRequest
            try:

                f = open(getFilename)

           #打开文件失败就说明,该网页不存在返回404

            except Exception:
                responseHeaders = 'HTTP/1.1 404 not found\r\n'
                responseHeaders += '\r\n'
                responseBody = "===Sorry,the page not found==="
            else:
                responseHeaders = 'HTTP/1.1 200 ok\r\n'
                responseHeaders += '\r\n'
                responseBody = f.read()
            finally:
                response = responseHeaders + responseBody
                connfd.send(response.encode())
        else:
            #通过函数得到响应体
            responseBody = self.application()
            responseHeaders = 'HTTP/1.1 200 ok\r\n'
            responseHeaders += '\r\n'
            response = responseHeaders + responseBody
            connfd.send(response.encode())

    #获取你要使用的外部函数,变为属性
    def setApp(self,application):
        self.application = application

def app():
    return time.ctime()


if __name__ == "main":
    httpd = HTTPServer(ADDR)
    httpd.setApp(app)
    #启动服务器
    httpd.serve_forever()
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是一个简单的基于 Linux C 多线程HTTP 服务器示例,使用了 POSIX 线程库和 socket 编程接口: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <pthread.h> #include <sys/socket.h> #include <netinet/in.h> #define PORT 8080 #define MAX_CONNECTIONS 10 #define BUFFER_SIZE 1024 void *handle_connection(void *arg) { int conn_fd = *(int*)arg; char buffer[BUFFER_SIZE]; ssize_t n; memset(buffer, 0, sizeof(buffer)); n = read(conn_fd, buffer, sizeof(buffer)-1); if (n <= 0) { close(conn_fd); pthread_exit(NULL); } char *response = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\nHello, world!"; write(conn_fd, response, strlen(response)); close(conn_fd); pthread_exit(NULL); } int main() { int sock_fd, conn_fd; struct sockaddr_in serv_addr, client_addr; socklen_t client_len; pthread_t threads[MAX_CONNECTIONS]; // create socket sock_fd = socket(AF_INET, SOCK_STREAM, 0); if (sock_fd < 0) { perror("Failed to create socket"); exit(EXIT_FAILURE); } // set server address memset(&serv_addr, 0, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = INADDR_ANY; serv_addr.sin_port = htons(PORT); // bind socket to server address if (bind(sock_fd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) { perror("Failed to bind socket"); exit(EXIT_FAILURE); } // listen for connections if (listen(sock_fd, MAX_CONNECTIONS) < 0) { perror("Failed to listen for connections"); exit(EXIT_FAILURE); } printf("HTTP server is listening on port %d\n", PORT); // handle connections in separate threads while (1) { client_len = sizeof(client_addr); conn_fd = accept(sock_fd, (struct sockaddr*)&client_addr, &client_len); if (conn_fd < 0) { perror("Failed to accept connection"); continue; } pthread_t thread; if (pthread_create(&thread, NULL, handle_connection, &conn_fd) < 0) { perror("Failed to create thread"); close(conn_fd); continue; } pthread_detach(thread); } return 0; } ``` 上述代码创建了一个监听在 8080 端口的 HTTP 服务器,可以处理多个连接。在每个连接到来时,都会创建一个新的线程来处理请求。在处理请求的线程中,首先读取请求消息,然后发送一个简单的响应消息。 需要注意的是,在多线程环境下,需要使用线程安全的函数和数据结构,以避免竞争条件和死锁。例如,在本例中,每个线程都需要使用不同的连接套接字(conn_fd),因此需要将套接字的值作为线程参数传递,而不是直接使用全局变量。同时,需要注意在每个线程中关闭连接套接字,以避免资源泄漏。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值