主要使用了socket库
1.显示固定的页面
import socket
def client_server(client_socket):
recv_data = client_socket.recv(1024).decode('utf-8')
recv_info = recv_data.splitlines()
for i in recv_info:
print(i)
reply_head = 'HTTP/1.1 200 OK \r\n'
reply_head += '\r\n'
reply_body = 'Hello world!'
client_socket.send((reply_head + reply_body).encode('utf-8'))
client_socket.close()
def main():
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server.bind(("", 7789))
server.listen(128)
while True:
client_socket, client_addr = server.accept()
client_server(client_socket)
if __name__ == '__main__':
main()
运行之后就在本地建立起了一个TCP服务端,可以使用浏览器访问本地的网址看到Hello world!内容,同时服务端会打印信息
2.页面访问
import socket
import re
def client_server(client_socket):
# 打印信息
recv_data = client_socket.recv(1024).decode('utf-8', errors='ignore')
data_info = recv_data.splitlines()
for i in data_info:
print(i)
# 获取输入的信息(地址)
target = data_info[0]
target_file = re.match('[^/]+(/[^ ]*)', target).group(1)
print("file name is " + target_file)
if target_file is '/':
location = DOCUMENTS_ROOT + '/index.html'
else:
location = DOCUMENTS_ROOT + target_file
try:
f = open(location, 'rb')
except IOError:
reply_head = 'HTTP/1.1 404 not found\r\n'
reply_head += '\r\n'
reply_body = b'not found'
else:
reply_head = 'HTTP/1.1 200 OK \r\n'
reply_head += '\r\n'
reply_body = f.read()
f.close()
finally:
# 先返回head
client_socket.send(reply_head.encode('utf-8'))
# 再返回body
client_socket.send(reply_body)
client_socket.close()
def main():
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server.bind(("", 7788))
server.listen(128)
while True:
client_socket, client_addr = server.accept()
client_server(client_socket)
DOCUMENTS_ROOT = './html'
if __name__ == '__main__':
main()
这样就可以访问根目录中html文件夹下面的内容,例如:(提前保存了一个百度网页)
3.使用多进程
import socket
from multiprocessing import Process
from 页面访问 import client_server
DOCUMENTS_ROOT = './html'
SERVER_ADDR = (ADDR, PORT) = ("", 7788)
class WebServer():
def __init__(self, addr):
self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.server.bind(addr)
self.server.listen(128)
def run_last(self):
while True:
client_socket, client_port = self.server.accept()
print("address:" + str(client_port) + "connected")
p = Process(target=self.client((client_socket)))
p.start()
# 因为已经将socket复制到了另一个子线程中,因此主线程的socket可以关闭
client_socket.close()
def client(self, client_socket):
client_server(client_socket)
def main():
http_server = WebServer(SERVER_ADDR)
print("Server start on port:" + str(PORT))
http_server.run_last()
if __name__ == '__main__':
main()
client部分直接继承第二个部分,多进程保证了可以同时处理多个网页请求
解决了一个问题:只打开主页的时候什么都不输入会数组空长报错,于是引入了try报错机制,使用except解决了不输入具体目录的问题
4.使用多线程实现
import socket
from threading import Thread
from 显示内容 import client_server
DOCUMENTS_ROOT = './html'
SERVER_ADDR = (ADDR, PORT) = ("", 7788)
class WebServer():
def __init__(self, addr):
self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.server.bind(addr)
# 转变为监听状态
self.server.listen(128)
def run_last(self):
while True:
clinet_socket, client_port = self.server.accept()
t = Thread(target=self.client(clinet_socket))
print('address:' + str(client_port) + ' connected')
t.start()
clinet_socket.close()
def client(self, client_socket):
client_server(client_socket)
def main():
http_server = WebServer(SERVER_ADDR)
print("Server is start on port:" + str(PORT))
http_server.run_last()
if __name__ == '__main__':
main()
解决了一个问题:
使用多线程实现的时候,浏览器在刷新的时候会报错,会显示软件中断了连接,这里需要在显示页面部分中添加报错机制
try:
# 先返回head
client_socket.send(reply_head.encode('utf-8'))
# 再返回body
client_socket.send(reply_body)
client_socket.close()
except ConnectionAbortedError:
pass
https://bbs.csdn.net/topics/392188437
即可解决问题