web request
#模拟浏览器请求web服务器
import socket
tcpSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #创建套接字
tcpSocket.connect(("121.36.32.38",80))
requestLine = "GET / HTTP/1.1\r\n"
requestHeader = "host:www.yaojun.com\r\n"
requestBlank = "\r\n"
requestData = requestLine + requestHeader + requestBlank
tcpSocket.send(requestData.encode()) #已经建立了连接 直接发送
receiveData = tcpSocket.recv(4096)
receiveText = receiveData.decode()
loc = receiveText.find("\r\n\r\n")
html = receiveText[loc+4:]
with open("index.html","w+") as f:
f.write(html)
tcpSocket.close()
web response
返回浏览器固定数据
import socket
def requestHandler(newsocket,ipPort):
receiveData = newsocket.recv(1024)
if not receiveData:
print("%s客户端已经断开!"%str(ipPort))
newsocket.close()
return
responseLine="HTTP/1.1 200 OK\r\n"
responseHeader ="Server:Python20WS/2.1\r\n"
responseBlank ="\r\n"
responseBody="hello world!"
responseData = responseLine+responseHeader+responseBlank+responseBody
newsocket.send(responseData.encode())
newsocket.close()
pass
def main():
tcpSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #创建套接字
tcpSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
tcpSocket.bind(("",8080)) #元组
tcpSocket.listen(128) #监听上限 在windows 128有效 在linux无效
while True:
newSocket,ipPort = tcpSocket.accept() #阻塞等待客户端连接 ipPort是个元组只有两个元素
print(ipPort[0]) #IP
print(ipPort[1]) #port
requestHandler(newSocket,ipPort)
if __name__ == '__main__':
main()
Web Server
从浏览器打开返回固定页面
import socket
def requestHandler(newsocket,ipPort):
receiveData = newsocket.recv(1024)
if not receiveData:
print("%s客户端已经断开!"%str(ipPort))
newsocket.close()
return
responseLine="HTTP/1.1 200 OK\r\n"
responseHeader ="Server:Python20WS/2.1\r\n"
responseBlank ="\r\n"
#从文件中读入固定页面
with open("index.html", "rb") as f:
responseBody = f.read() #读入的是二进制文件
responseData = (responseLine+responseHeader+responseBlank).encode()+responseBody
newsocket.send(responseData)
newsocket.close()
pass
def main():
tcpSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #创建套接字
tcpSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
tcpSocket.bind(("",8080)) #元组
tcpSocket.listen(128) #监听上限 在windows 128有效 在linux无效
while True:
newSocket,ipPort = tcpSocket.accept() #阻塞等待客户端连接 ipPort是个元组只有两个元素
print(ipPort[0]) #IP
print(ipPort[1]) #port
requestHandler(newSocket,ipPort)
if __name__ == '__main__':
main()
Web Server
返回指定页面localhost:8080/index.html
注意需要在当前目录下增加一个favicon.ico文件
import socket
def requestHandler(newsocket,ipPort):
receiveData = newsocket.recv(1024)
if not receiveData:
print("%s客户端已经断开!"%str(ipPort))
newsocket.close()
return
#拆分请求
receiveText = receiveData.decode()
loc = receiveText.find("\r\n")
requestLine= receiveText[:loc].split()
filePath = requestLine[1]
if filePath == "/":
filePath = "index.html"
else:
filePath = filePath[1:]
responseLine="HTTP/1.1 200 OK\r\n"
responseHeader ="Server:Python20WS/2.1\r\n"
responseBlank ="\r\n"
#从文件中读入固定页面 如果页面不存在使用异常捕获
try:
with open(filePath, "rb") as f:
responseBody = f.read() #读入的是二进制文件
except Exception as e:
responseLine = "HTTP/1.1 404 Not Found\r\n"
responseBody = "Error!%s"%str(e)
responseBody = responseBody.encode() #编码为二进制
responseData = (responseLine+responseHeader+responseBlank).encode() + responseBody
newsocket.send(responseData)
newsocket.close()
def main():
tcpSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #创建套接字
tcpSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
tcpSocket.bind(("",8080)) #元组
tcpSocket.listen(128) #监听上限 在windows 128有效 在linux无效
while True:
newSocket,ipPort = tcpSocket.accept() #阻塞等待客户端连接 ipPort是个元组只有两个元素
print(ipPort[0]) #IP
print(ipPort[1]) #port
requestHandler(newSocket,ipPort)
if __name__ == '__main__':
main()
面向对象封装
import socket
class WebServer(object):
def __init__(self):
tcpSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 创建套接字
tcpSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
tcpSocket.bind(("", 8080)) # 元组
tcpSocket.listen(128) # 监听上限 在windows 128有效 在linux无效
self.tcpSocket = tcpSocket
def start(self):
while True:
newSocket, ipPort = self.tcpSocket.accept() # 阻塞等待客户端连接 ipPort是个元组只有两个元素
print(ipPort[0]) # IP
print(ipPort[1]) # port
self.requestHandler(newSocket, ipPort)
def requestHandler(self, newsocket,ipPort):
receiveData = newsocket.recv(1024)
if not receiveData:
print("%s客户端已经断开!"%str(ipPort))
newsocket.close()
return
#拆分请求
receiveText = receiveData.decode()
loc = receiveText.find("\r\n")
requestLine= receiveText[:loc].split()
filePath = requestLine[1]
if filePath == "/":
filePath = "/index.html"
responseLine="HTTP/1.1 200 OK\r\n"
responseHeader ="Server:Python20WS/2.1\r\n"
responseBlank ="\r\n"
#从文件中读入固定页面 如果页面不存在使用异常捕获
try:
with open("staticPage"+filePath, "rb") as f:
responseBody = f.read() #读入的是二进制文件
except Exception as e:
responseLine = "HTTP/1.1 404 Not Found\r\n"
responseBody = "Error!%s"%str(e)
responseBody = responseBody.encode() #编码为二进制
responseData = (responseLine+responseHeader+responseBlank).encode() + responseBody
newsocket.send(responseData)
newsocket.close()
def main():
ws = WebServer()
ws.start()
if __name__ == '__main__':
main()
服务端基础框架构建
分模块
子文件:staticPage application
import socket
#导入模块
from application import app
class WebServer(object):
def __init__(self):
tcpSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 创建套接字
tcpSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
tcpSocket.bind(("", 8080)) # 元组
tcpSocket.listen(128) # 监听上限 在windows 128有效 在linux无效
self.tcpSocket = tcpSocket
def start(self):
while True:
newSocket, ipPort = self.tcpSocket.accept() # 阻塞等待客户端连接 ipPort是个元组只有两个元素
self.requestHandler(newSocket, ipPort)
def requestHandler(self, newsocket,ipPort):
receiveData = newsocket.recv(1024)
if not receiveData:
print("%s客户端已经断开!"%str(ipPort))
newsocket.close()
return
#拆分请求
responseData = app.app("staticPage", receiveData, ipPort)
newsocket.send(responseData)
newsocket.close()
def main():
ws = WebServer()
ws.start()
if __name__ == '__main__':
main()
应用模块
def parseRequest(receiveData, ipPort):
'''解析请求的报文 返回客户端请求的资源路径'''
receiveText = receiveData.decode()
loc = receiveText.find("\r\n")
requestLine = receiveText[:loc].split(" ")
filePath = requestLine[1]
print("%s正在请求:%s" % (str(ipPort), filePath))
if filePath == "/":
filePath = "/index.html"
return filePath
def app(currentDir, receiveData,ipPort):
filePath = parseRequest(receiveData, ipPort)
resourcePath = currentDir + filePath
responseLine = "HTTP/1.1 200 OK\r\n"
responseHeader = "Server:Python20WS/2.1\r\n"
responseBlank = "\r\n"
# 从文件中读入固定页面 如果页面不存在使用异常捕获
try:
with open(resourcePath, "rb") as f:
responseBody = f.read() # 读入的是二进制文件
except Exception as e:
responseLine = "HTTP/1.1 404 Not Found\r\n"
responseBody = "Error!%s" % str(e)
responseBody = responseBody.encode() # 编码为二进制
responseData = (responseLine + responseHeader + responseBlank).encode() + responseBody
return responseData
Web Server
带命令行参数
import socket
import sys
#导入模块
from application import app
class WebServer(object):
def __init__(self,port):
tcpSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 创建套接字
tcpSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
tcpSocket.bind(("", port)) # 元组
tcpSocket.listen(128) # 监听上限 在windows 128有效 在linux无效
self.tcpSocket = tcpSocket
def start(self):
while True:
newSocket, ipPort = self.tcpSocket.accept() # 阻塞等待客户端连接 ipPort是个元组只有两个元素
self.requestHandler(newSocket, ipPort)
def requestHandler(self, newsocket,ipPort):
receiveData = newsocket.recv(1024)
if not receiveData:
print("%s客户端已经断开!"%str(ipPort))
newsocket.close()
return
#拆分请求
responseData = app.app("staticPage", receiveData, ipPort)
newsocket.send(responseData)
newsocket.close()
def main():
paraList=sys.argv
if len(paraList)==2 and paraList[1].isdigit():
print("启动成功!")
else:
print("启动失败!参数错误或者端口不是数字")
return
port = int(paraList[1])
ws = WebServer(port)
ws.start()
if __name__ == '__main__':
main()
app模块
from application import utils
def parseRequest(receiveData, ipPort):
'''解析请求的报文 返回客户端请求的资源路径'''
receiveText = receiveData.decode()
loc = receiveText.find("\r\n")
requestLine = receiveText[:loc].split(" ")
filePath = requestLine[1]
print("%s正在请求:%s" % (str(ipPort), filePath))
if filePath == "/":
filePath = "/index.html"
return filePath
def app(currentDir, receiveData,ipPort):
filePath = parseRequest(receiveData, ipPort)
resourcePath = currentDir + filePath
# 从文件中读入固定页面 如果页面不存在使用异常捕获
try:
with open(resourcePath, "rb") as f:
responseBody = f.read() # 读入的是二进制文件
responseData = utils.CreateHttpResponse("200 OK", responseBody)
except Exception as e:
responseBody = "Error!%s" % str(e)
responseBody = responseBody.encode() # 编码为二进制
responseData = utils.CreateHttpResponse("404 Not Found", responseBody)
return responseData
utils模块
def CreateHttpResponse(status, responseBody):
'''返回响应数据'''
responseLine = "HTTP/1.1 %s\r\n" % status
responseHeader = "Server:Python20WS/2.1\r\n"
responseBlank = "\r\n"
responseData = (responseLine + responseHeader + responseBlank).encode() + responseBody
return responseData