Python을 사용하여 간단한 HTTP 서버를 작성하는 방법은 무엇입니까?

王林
풀어 주다: 2023-05-07 22:25:06
앞으로
1772명이 탐색했습니다.

http

http는 애플리케이션 계층 프로토콜입니다. 정확하게 말하면 TCP/IP의 전송 계층에 있는 TCP를 기반으로 합니다. 레이어 네트워크 프로토콜 애플리케이션 레이어 프로토콜. http是一个应用层协议,准确的来说是基于TCP/IP4层网络协议中的传输层中的TCP应用层协议。

额,4层模型大概是这样的:

Python을 사용하여 간단한 HTTP 서버를 작성하는 방법은 무엇입니까?

在网络通信中,用户的数据是以报文来传输的,但是在实际通信中,每一层都会对包进行封装,从而形成段、数数据报、帧,最后是以比特流(二进制)进行传输,到了目标主机后,会对每一层又进行拆解,从而得到最后的报文。

http就在最上层,就是应用层那里。

http到底离我们多近呢? 甚至于你现在看到的文章,使用的就是http协议,它还有一个名字,叫做超文本传输协议,为什么叫超文本呢? 因为最开始的是时候,http是被用来传输Hypertext文档的,所以被叫做超文本协议,当然现在可以传输其他类型的数据,如: 视频、音频、图片等,但是它依然被称之为超文本协议。

很难理解吧,没关系,继续往下看。

分析http请求报文和响应报文格式

通过上面的简介,我们知道http是应用层协议,它在网络协议中,是被称之为报文的,让我们来看一下http的请求报文 和 响应报文吧。

http报文由4部分组成,分别是起始行、首部行、空白行 以及 实体组成。以rn(也称之为CRLF)进行分割。

让我们来看一下实际的报文呢。

linux中,我们可以使用curl -v 网址来打印详细的请求信息,其中就包括了报文。

命令:

curl -v http://juejin.cn
로그인 후 복사

请求信息:

Python을 사용하여 간단한 HTTP 서버를 작성하는 방법은 무엇입니까?

其中输出的结果中> 代表我们发出的报文,而< 代表服务器发送给我们的响应信息。下面我们将结合报文来看上面的数据信息。

请求报文格式如下:

Python을 사용하여 간단한 HTTP 서버를 작성하는 방법은 무엇입니까?

其中请求行会指定http的请求方法,如: GETPOSTHEAD等, URL则是请求的文件路径,协议版本需要指定http的版本,最后是以CRLF结束。

首部行可以有多个,以 (字段名: 值) 的方式出现,每一个首部行同样是以CRLF结束。

而后是空行。空行则代表http报文头结束了,接下来该是发送的报文主体了,接下来,我们将上述请求http://juejin.cn的例子,填入表格来看下:

Python을 사용하여 간단한 HTTP 서버를 작성하는 방법은 무엇입니까?

上述是我们使用curl工具请求的http://juejin.cn请求报文整体形式,我们可以看到,我们使用了GET方法,获取服务器的/信息,使用的协议是HTTP/1.1,而后携带了3个首部行,分别是User-AgentHost以及Accept

响应报文格式如下:

Python을 사용하여 간단한 HTTP 서버를 작성하는 방법은 무엇입니까?

将响应报文和请求报文进行对比,我们不难发现,除了第一行以外,其他的格式都是一样的,所以,我们仅介绍响应行的信息,在响应报行中,第一个是协议的版本,这个是服务器的协议版本,而后便是状态码,用于告知客户端,服务器响应的信息,最后是短语,短语的作用是告知使用者,这个返回信息大概是什么意思。

好了,我们将上述juejin.cn响应给我们的报文,我们填到表格中呢:

Python을 사용하여 간단한 HTTP 서버를 작성하는 방법은 무엇입니까?

上述是我们使用curl请求http://juejin.cn/,服务器返回的信息,我们逐行来看下,响应行,告知了我们http版本是HTTP/1.1,状态码是301,短语是 链接被转移了。

上述我们若仅通过状态码的话,是很难get

글쎄, 4레이어 모델은 다음과 같습니다.🎜🎜작성 방법 Python 기반의 간단한 http 서버입니다.🎜🎜네트워크 통신에서는 사용자 데이터가 메시지로 전송되지만, 실제 통신에서는 각 계층이 패킷을 캡슐화하여 세그먼트, 데이터그램, 프레임을 형성하고, 최종적으로는 비트 스트림(바이너리). 대상 호스트에 도착한 후 각 계층은 최종 메시지를 얻기 위해 분해됩니다. 🎜🎜http는 애플리케이션 계층인 최상위 계층에 있습니다. 🎜🎜http는 우리와 얼마나 가깝나요? 지금 보고 있는 기사도 httphttp하이퍼텍스트http가 애플리케이션 계층 프로토콜이라는 것을 알았습니다. 이를 네트워크 프로토콜에서는 메시지라고 합니다. http의 요청 메시지와 응답 메시지입니다. 🎜🎜httprn(CRLF라고도 함)으로 분할합니다. 🎜🎜실제 메시지를 살펴보겠습니다. 🎜🎜linux에서는 curl -v URL을 사용하여 메시지를 포함한 자세한 요청 정보를 인쇄할 수 있습니다. 🎜🎜명령:🎜
import socket
import threading

def handle(client , addr):
    print("from " , addr)
    data = client.recv(1024)
    for k,v in enumerate(data.decode().split("\r\n")):
        print(k ,v)

def main():
    s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    s.bind(("127.0.0.1",8080))
    s.listen()
    
    while True:
        client , addr = s.accept() 
        t = threading.Thread(target=handle,args=(client,addr))
        t.start()

if __name__ == &#39;__main__&#39;
    main()
로그인 후 복사
로그인 후 복사
🎜요청 정보:🎜🎜간단한 프로그램 작성 방법 based on Python http server🎜🎜출력 결과에서 > 는 우리가 보낸 메시지를 나타내고, < 는 서버가 우리에게 보낸 응답 정보를 나타냅니다. . 다음으로 위의 데이터 정보를 메시지와 함께 살펴보겠습니다. 🎜🎜요청 메시지 형식은 다음과 같습니다.🎜🎜간단한 http 작성 방법 Python 서버 기반🎜🎜요청 줄은 GET, POST, 와 같은 <code>http의 요청 방법을 지정합니다. >HEADURL은 요청된 파일 경로이고 프로토콜 버전은 httpCRLF<로 끝납니다. /코드>. 🎜🎜(필드 이름: 값) 형식으로 여러 헤더 행이 나타날 수 있습니다. 각 헤더 행도 <code>CRLF로 끝납니다. 🎜🎜그러면 빈 줄이 있습니다. 빈 줄은 httphttp://juejin.cn<을 작성하겠습니다. /code> 예를 들어, 양식을 작성하고 살펴보세요: 🎜🎜How Python http 서버 기반의 간단한 프로그램 작성🎜🎜위는 curl을 사용하는 http://juejin.cnGET/HTTP/1.1입니다. , User-Agent, HostAccept라는 세 개의 헤더 줄을 전달합니다. 🎜🎜응답 메시지 형식은 다음과 같습니다.🎜🎜간단한 http 작성 방법 based on Python Server🎜🎜응답 메시지와 요청 메시지를 비교해 보세요. 첫 번째 줄을 제외하면 다른 형식이 동일하다는 것을 찾는 것은 어렵지 않습니다. 따라서 응답 줄의 정보만 소개합니다. 그 중 첫 번째는 서버의 프로토콜 버전인 프로토콜 버전이고, 그 다음에는 클라이언트에게 서버 응답 정보를 알리는 데 사용되는 상태 코드가 있습니다. 이 문구의 기능은 반환 정보가 무엇을 의미하는지에 관한 것임을 사용자에게 알리는 것입니다. 🎜🎜좋아요, juejin.cn에서 보낸 위의 메시지를 다음 형식에 입력해 보겠습니다.🎜🎜Python 기반의 간단한 http 서버 작성 방법🎜🎜위는 curl을 사용하여 http://를 요청하는 곳입니다. juejin.cn/, 서버에서 반환하는 정보를 한 줄씩 살펴보겠습니다. 응답 줄은 httpHTTP/1.1임을 알려줍니다. 상태 코드는 301이고 링크가 이동되었다는 문구입니다. 🎜🎜위의 상태 코드만 사용하면 전체 메시지의 의미를 알아내기首部行,告知了我们服务器 、时间 、 报文类型 以及 报文长度。还记得我们第一段落介绍过得,http现在除了发送超文本以外,还可以发送图片、视频等,就是通过首部行Content-Type来确定的。

接着是空白行,最后是报文主体,哎,有没有感觉奇怪呢?为什么请求报文主体是空的呢?这是因为报文主体长度是由首部行Content-Length来定义的,如上报文展示的是,我们报文主体有262个字符。

手写一个简单的http服务器

上述,我们介绍了,什么是http以及初略的看了一下 http的请求报文和响应报文,那么,我们如何构建一个http服务器呢?

我们知道,http是应用层协议,是基于传输层tcp来实现的,所以,我们若想构建一个http服务器,那么应该写一个socket程序出来吧。

import socket
import threading

def handle(client , addr):
    print("from " , addr)
    data = client.recv(1024)
    for k,v in enumerate(data.decode().split("\r\n")):
        print(k ,v)

def main():
    s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    s.bind(("127.0.0.1",8080))
    s.listen()
    
    while True:
        client , addr = s.accept() 
        t = threading.Thread(target=handle,args=(client,addr))
        t.start()

if __name__ == &#39;__main__&#39;
    main()
로그인 후 복사
로그인 후 복사

上述,我们写了一个tcp程序,它将监听本地回环地址的8080端口,若此时我们使用curl -v 127.0.0.1:8080请求一下该接口,我们将会得到请求报文了,如下:

Python을 사용하여 간단한 HTTP 서버를 작성하는 방법은 무엇입니까?

我们得到请求报文后,可以构建一个响应报文发送回去,例如: Hello, Destined Person.,我们就可以这样来构建http

import socket
import threading

def handle(client , addr):
    print("from " , addr)
    data = client.recv(1024)
    
    #请求报文
    for k,v in enumerate(data. decode() .split("\r\n")):
        print(k ,v)
        
    bodyText = "He1lo,Destined Person."
    #响应报文
    #响应行
    client.send(b"HTTP/1.1 200 OK\r\n")
    #首部行
    client. send(b"Server: pdudo_web_sites\r\n") 
    client. send(b"Content-Type: text/html\r\n")
    client. send(("Content-Length: %s\r\n" % (len(bodyText) + 2)).encode())
    client. send(b"\r\n")
    client. send(("%s\r\n" %(bodyText)).encode())
    
def main():
    try:
        s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        s .bind(("127.0.0.1"8080))
        s .listen()
        
        while True:
            client,addr = s.accept()
            t = threading.Thread(target=handle,args=(client,addr))
            t.start()
    finally:
        s.close()

if __name__ == &#39;__main__&#39;:
    main()
로그인 후 복사

最后我们使用curl再来测试一下,是可以得到消息的。

Python을 사용하여 간단한 HTTP 서버를 작성하는 방법은 무엇입니까?

위 내용은 Python을 사용하여 간단한 HTTP 서버를 작성하는 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:yisu.com
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿