python实现http服务器_用python编写http server(1)-简单服务器

对于wsgi来说,http server主要是处理了http请求,并提取了http请求的部分信息。http server最重要的还是通过多线程、多进程、协程等来处理并发请求。我们可以通过自己编写http server来熟悉整个请求处理流程,这里我们只关心tcp层。

先来个最简单的server

import socket

class SimpleServer():

def __init__(self, host, port):

self.connect = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM, proto=socket.IPPROTO_TCP)

# 处理TIME_WAIT

self.connect.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

self.connect.bind((host, port))

def serve_forever(self):

self.connect.listen()

while 1:

try:

conn, addr = self.connect.accept()

except KeyboardInterrupt:

break

print('Connected by', addr)

self.handle_request(conn)

self.connect.close()

def handle_request(self, conn):

data = conn.recv(1024)

print(data)

conn.close()

if __name__ == "__main__":

server = SimpleServer("localhost", 8000)

server.serve_forever()

socket.socket可以创建多种类型的socket,这里主要测试ipv4的tcp。

可以看到创建完socket使用了setsockopt函数。这里有一个很有趣的现象是,如果去掉这函数,重新启动server时,会提示端口已绑定。这是因为tcp四次挥手时,首先关闭的一方有个TIME_WAIT2,设置了端口重用后就可以立刻重新启动了。

新开启个console:$ curl http://localhost:8000

可以看到server有了反应:

Connected by ('127.0.0.1', 59490)

b'GET / HTTP/1.1\r\nHost: localhost:8000\r\nUser-Agent: curl/7.58.0\r\nAccept: /\r\n\r\n'

为了模拟单进程单线程server的问题,我们在handle_request函数里增加个time.sleep(5)

def handle_request(self, conn):

data = conn.recv(1024)

print(data)

time.sleep(5)

conn.close()

同时启动多个console,输入curl http://localhost:8000

可以看到server在第一个curl 处理完后才开始处理第二个curl ,期间第二个curl一直被阻塞。

这里必须明确的是,其实第二个curl的请求已经发送到server端了,但因为curl一直在等待server结束连接,所以一直在阻塞。

程序调用socket的write函数时,数据从程序缓冲区复制至socket发送缓冲区,在对端ack返回确认发送成功后就从write函数返回。

可以写个简单的client验证:

import socket

class SimpleClient():

def __init__(self, host, port):

self.connect = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM, proto=socket.IPPROTO_TCP)

self.connect.connect((host, port))

def sendall(self, _bytes):

self.connect.sendall(_bytes)

self.connect.close()

if __name__ == "__main__":

server = SimpleClient("localhost", 8000)

server.sendall(b"hello,word")

先启动curl,然后启动client,可以发现client发送完数据后直接结束。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值