写在前面
最近在学习Django,对于底层的信息交换产生了些许兴趣,而且前段时间看一个同事使用c++写socket,今天我查了点资料,自己也写写试试
用到的包
#socket相关
from socket import *
#线程相关
from threading import Thread
#系统模块
import os
#正则匹配,从请求中匹配html文件路径
import re
筛查请求
def get_request_name_from_http(http:str) -> str:
#从请求中匹配静态文件地址
r = re.search(r"GET /(.+?) ",http)
filename = ""
if r != None:
filename = r.group(1)
#返回相对路径的文件地址
return filename
服务器数据
#构建Response header和Response数据,并从服务器发送给用户
def writeHtml(client,filename):
rspHead = None
rspBody = None
if not os.path.exists(filename):
rspHead = "HTTP/1.1 404 error\r\nServer: foreverServer\r\n\r\n"
rspBody = "file not found"
else:
rspHead = "HTTP/1.1 200 OK\r\nServer: foreverServer\r\n\r\n"
html = open(filename,'r',encoding="UTF-8")
rspBody = html.read()
client.send((rspHead + rspBody).encode('UTF-8'))
线程调用函数
def deal_socket(client):
try:
#1024代表请求的最大字节数
data = client.recv(1024)
if len(data) > 0:
#获取目标html文件地址
fileName = get_request_name_from_http(data.decode("utf-8"))
#获取Response信息后发送到客户端
writeHtml(client, fileName)
finally:
#关闭连接
client.close()
主函数
def main():
#初始化socket服务
server = socket(AF_INET,SOCK_STREAM)
server.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
#ip和端口,默认为localhost(127.0.0.1)
address = ('',8000)
#与端口绑定
server.bind(address)
#监听,括号内为限制连接数量
server.listen(10)
try:
while True:
#初始化连接
client,client_address = server.accept()
#输出服务器ip和端口
print(client_address)
#初始化一个线程
p = Thread(target=deal_socket,args=(client,))
#启动线程
p.start()
except Exception as e:
print(e)
finally:
#关闭服务器
server.close()
完整代码
# -*- coding: utf-8 -*-
"""
Created on Thu Feb 18 18:40:58 2021
@author: Administrator
"""
from socket import *
from threading import Thread
import os
import re
def get_request_name_from_http(http:str) -> str:
r = re.search(r"GET /(.+?) ",http)
filename = ""
if r != None:
filename = r.group(1)
return filename
def writeHtml(client,filename):
rspHead = None
rspBody = None
if not os.path.exists(filename):
rspHead = "HTTP/1.1 404 error\r\nServer: foreverServer\r\n\r\n"
rspBody = "file not found"
else:
rspHead = "HTTP/1.1 200 OK\r\nServer: foreverServer\r\n\r\n"
html = open(filename,'r',encoding="UTF-8")
rspBody = html.read()
client.send((rspHead + rspBody).encode('UTF-8'))
def deal_socket(client):
try:
data = client.recv(1024)
if len(data) > 0:
fileName = get_request_name_from_http(data.decode("utf-8"))
writeHtml(client, fileName)
finally:
client.close()
def main():
server = socket(AF_INET,SOCK_STREAM)
server.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
address = ('',8000)
server.bind(address)
server.listen(10)
try:
while True:
client,client_address = server.accept()
print(client_address)
p = Thread(target=deal_socket,args=(client,))
p.start()
except Exception as e:
print(e)
finally:
server.close()
if __name__ == '__main__':
main()
html和访问
在py文件同目录下新建index.html:
<!DOCTYPE html>
<head>
<title>index</title>
</head>
<body>
<h1>Hello World!</h1>
</body>
运行py文件,在浏览器访问127.0.0.1:8000/index.html
即可
写在后面
代码是从简书抄来的,下午的时候用的是另一个代码,使用的是Process而非Thread,但是在这里发现了一个小问题,代码封装成类后无法正常访问,明天有空再Debug。