Web服务器是指驻留于因特网上某种类型计算机的程序。当Web浏览器(客户端)连到服务器上并请求文件时,服务器将处理该请求并将文件发送到该浏览器上,附带的信息会告诉浏览器如何查看该文件(即文件类型)。服务器使用HTTP(超文本传输协议)进行信息交流,这就是人们常把它们称为HTTPD服务器的原因。
这个东西挺复杂的内容也挺多,建议看看计算机网络教材关于服务器的章节。
import socket
import re
def service_client(new_socket, request):
#为这个客户端返回数据
# 1. 接收浏览器发送过来的请求,即http请求
# GET / HTTP/1.1
# ……
# request = new_socket.recv(1024).decode("utf-8")
# print(">>>" * 20)
# print(request)
request_lines = request.splitlines()
print("")
print(">" *20)
print(request_lines)
# GET /index.html HTTP/1.1
# get post put del
ret = re.match(r"[^/]+(/[^ ]*)", request_lines[0])
file_name =""
if ret:
file_name = ret.group(1)
print("*" *50, file_name)
if file_name =='/':
file_name ='/index.html'
# 2. 返回http格式的数据给浏览器
try:
# f = open("../buickmall/index.html", "rb")
f = open("../buickmall" + file_name, "rb")
except:
response ="HTTP/1.1 404 NOT FOUND\r\n"
response +="\r\n"
response +="---file not found---"
new_socket.send(response.encode("utf-8"))
else:
html_content = f.read()
f.close()
# 2.2 准备发送给浏览器的数据:Body
response_body = html_content
# 2.1 准备发送给浏览器的数据:Header
response_header ="HTTP/1.1 200 OK\r\n"
response_header +="Content-Length:%d\r\n" % len(response_body)
response_header +="\r\n"
response = response_header.encode("utf-8") + response_body
# 将Response发送给浏览器
new_socket.send(response)
# 关闭套接字
# new_socket.close()·
def main():
"""用来完成整体的控制"""
# 1. 创建套接字
tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 2. 绑定
tcp_server_socket.bind(("", 7890))
# 3. 变为监听套接字
tcp_server_socket.listen(128)
tcp_server_socket.setblocking(False)# 将套接字变为非阻塞
client_socket_list = list()
while True:
# 4. 等待新客户端的链接
try:
new_socket, client_addr = tcp_server_socket.accept()
except Exceptionas ret:
pass
else:
new_socket.setblocking(False)
client_socket_list.append(new_socket)
for client_socketin client_socket_list:
try:
recv_data = client_socket.recv(1024).decode("utf-8")
except Exceptionas ret:
pass
else:
if recv_data:
# 5. 为这个客户端服务
service_client(client_socket, recv_data)
else:
client_socket.close()
client_socket_list.remove(client_socket)
# 6.关闭监听套接字
tcp_server_socket.close()
if __name__ =="__main__":
main()
import socket
import re
import select
def service_client(new_socket, request):
"""为这个客户端返回数据"""
# 1. 接收浏览器发送过来的请求,即http请求
# GET / HTTP/1.1
# ……
# request = new_socket.recv(1024).decode("utf-8")
# print(">>>" * 20)
# print(request)
request_lines = request.splitlines()
print("")
print(">" *20)
print(request_lines)
# GET /index.html HTTP/1.1
# get post put del
ret = re.match(r"[^/]+(/[^ ]*)", request_lines[0])
file_name =""
if ret:
file_name = ret.group(1)
print("*" *50, file_name)
if file_name =='/':
file_name ='/index.html'
# 2. 返回http格式的数据给浏览器
try:
# f = open("../buickmall/index.html", "rb")
f = open("../buickmall" + file_name, "rb")
except:
response ="HTTP/1.1 404 NOT FOUND\r\n"
response +="\r\n"
response +="---file not found---"
new_socket.send(response.encode("utf-8"))
else:
html_content = f.read()
f.close()
# 2.2 准备发送给浏览器的数据:Body
response_body = html_content
# 2.1 准备发送给浏览器的数据:Header
response_header ="HTTP/1.1 200 OK\r\n"
response_header +="Content-Length:%d\r\n" % len(response_body)
response_header +="\r\n"
response = response_header.encode("utf-8") + response_body
# 将Response发送给浏览器
new_socket.send(response)
# 关闭套接字
# new_socket.close()
def main():
"""用来完成整体的控制"""
# 1. 创建套接字
tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# 2. 绑定
tcp_server_socket.bind(("", 7890))
# 3. 变为监听套接字
tcp_server_socket.listen(128)
tcp_server_socket.setblocking(False)# 将套接字变为非阻塞
# 创建一个epoll对象
epl = select.epoll()
# 将监听套接字对应的fd注册到epoll中
epl.register(tcp_server_socket.fileno(), select.EPOLLIN)
fd_event_dict = dict()
while True:
fd_event_list = epl.poll()# 默认会阻塞,直到os检测到数据到来,通过事件通知的方式告诉程序,此时才会解阻塞
# [(fd, event), (……)]
# 参数fd:套接字对应的文件描述符
# 参数event:这个fd是什么事件,例如可调用recv接收等
for fd, eventin fd_event_list:
# 4. 等待新客户端的链接
if fd == tcp_server_socket.fileno():
new_socket, client_addr = tcp_server_socket.accept()
epl.register(new_socket.fileno(), select.EPOLLIN)
fd_event_dict[new_socket.fileno()] = new_socket
elif event == select.EPOLLIN:
# 判断已经链接的客户端是否有数据发送过来
recv_data = fd_event_dict[fd].recv(1024).decode("utf-8")
if recv_data:
# 5. 为这个客户端服务
service_client(fd_event_dict[fd], recv_data)
else:
fd_event_dict[fd].close()
epl.unregister(fd)
del fd_event_dict[fd]
# 6.关闭监听套接字
tcp_server_socket.close()
if __name__ =="__main__":
main()
import gevent
import time
from geventimport monkey
monkey.patch_all()
def f1(n):
for iin range(n):
print(gevent.getcurrent(), i)
time.sleep(0.5)
# gevent.sleep(0.5)
def f2(n):
for iin range(n):
print(gevent.getcurrent(), i)
time.sleep(0.5)
# gevent.sleep(0.5)
def f3(n):
for iin range(n):
print(gevent.getcurrent(), i)
time.sleep(0.5)
# gevent.sleep(0.5)
# print("---1---")
# g1 = gevent.spawn(f1, 5) # 参数f指定协程在哪执行,需要传参就直接写在后边
# print("---2---")
# g2 = gevent.spawn(f2, 5)
# print("---3---")
# g3 = gevent.spawn(f3, 5)
# print("---4---")
# g1.join()
# g2.join()
# g3.join()
gevent.joinall([
gevent.spawn(f1, 5),
gevent.spawn(f2, 5),
gevent.spawn(f3, 5)
])
import urllib.request
import gevent
from geventimport monkey
monkey.patch_all()
def downloader(img_name, img_url):
req = urllib.request.urlopen(img_url)
img_content = req.read()
with open(img_name, "wb")as f:
f.write(img_content)
def main():
gevent.joinall([
gevent.spawn(downloader, "1.jpg","https://rpic.douyucdn.cn/live-cover/appCovers/2019/10/27/6510444_20191027144840_small.jpg"),
gevent.spawn(downloader,"2.jpg","https://rpic.douyucdn.cn/appCovers/416825/20160915/802092c2192960b416832a28a59c373b_small.jpg")
])
if __name__ =="__main__":
main()
# 浏览器-->服务器发送的请求格式如下:
#
# # 表示请求的目标、协议版本
# POST / HTTP/1.1
# # 表示服务器的IP地址和端口
# Host: 127.0.0.1:8080
# # 表示是长链接
# Connection: keep-alive
# # 表示谷歌浏览器告诉服务器,浏览器可以处理https协议
# Upgrade-Insecure-Requests: 1
# # 表示浏览器的版本
# User-Agent: Mozilla/5.0 (Windows NT 10.0Win64x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.80 Safari/537.36
# # 表示浏览器可以接收什么样的格式
# Accept: text/html,application/xhtml+xml,application/xmlq=0.9,image/webp,image/apng,*/*q=0.8,application/signed-exchangev=b3
# # 表示能够接收的压缩格式
# Accept-Encoding: gzip, deflate, br
# # 表示能接收的语言,能接收中文
# Accept-Language: zh-CN,zhq=0.9
#
# username:tom
# password:123
#
# 服务器-->浏览器回送的数据格式如下:
# HTTP/1.1 200 OK
# Bdpagetype: 1
# Bdqid: 0x9dd09c83000204a0
# # 表示你的缓存是共享的、还是私有的,现在是私有的
# Cache-Control: private
# Connection: Keep-Alive
# # 编码格式,浏览器就按照这个格式来解压
# Content-Encoding: gzip
# # 服务器传回的内容格式、字符集
# Content-Type: text/htmlcharset=utf-8
# Content-Length: 123456789
# Cxy_all: baidu+34491ab9ca3c8ba32cebe1d26059f593
# # 表示服务器当前的时间
# Date: Sun, 23 Jun 2019 03:38:04 GMT
# Expires: Sun, 23 Jun 2019 03:37:52 GMT
# # 服务器:BWS是百度服务器的一个简称
# Server: BWS/1.1
# # 设置Cookie
# Set-Cookie: delPer=0path=/domain=.baidu.com
# Set-Cookie: BDSVRTM=0path=/
# Set-Cookie: BD_HOME=0path=/
# Set-Cookie: H_PS_PSSID=1441_21127_29135_29237_28518_29099_29131_29369_28833_29220_26350path=/domain=.baidu.com
# Strict-Transport-Security: max-age=172800
# Vary: Accept-Encoding
# X-Ua-Compatible: IE=Edge,chrome=1
# Transfer-Encoding: chunked
#
# <h1>hahaha</h1>
import socket
def service_client(new_socket):
"""为这个客户端返回数据"""
# 1. 接收浏览器发送过来的请求,即http请求
# GET / HTTP/1.1
# ……
request = new_socket.recv(1024)
print(request)
# 2. 返回http格式的数据给浏览器
# 2.1 准备发送给浏览器的数据:Header
response ="HTTP/1.1 200 OK\r\n"
response +="\r\n"
# 2.2 准备发送给浏览器的数据:Body
response +="
"
new_socket.send(response.encode("utf-8"))
# 关闭套接字
new_socket.close()
def main():
"""用来完成整体的控制"""
# 1. 创建套接字
tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# 2. 绑定
tcp_server_socket.bind(("", 7890))
# 3. 变为监听套接字(最大连接数是128)
tcp_server_socket.listen(128)
while True:
# 4. 等待新客户端的链接
new_socket, client_addr = tcp_server_socket.accept()
# 5. 为这个客户端服务
service_client(new_socket)
# 6.关闭监听套接字
tcp_server_socket.close()
if __name__ =="__main__":
main()
while true:
print('---1---')
time.sleep(0.1)
yield
def task_2():
while true:
print('---2---')
time.sleep(0.1)
yield
def main():
t1 = task_1()
t2 = task_2()
while true:
next(t1)
next(t2)
if __name__=="__main__":
import urllib.request
def main():
# req = urllib.request.urlopen("https://gss3.bdstatic.com/-Po3dSag_xI4khGkpoWK1HF6hhy/baike/whfpf%3D360%2C280%2C50/sign=71bcd12444fbfbeddc0c653f1ecdc400/18d8bc3eb13533faa998d335a7d3fd1f41345bfa.jpg")
req = urllib.request.urlopen("import urllib.request
def main():
# req = urllib.request.urlopen("https://gss3.bdstatic.com/-Po3dSag_xI4khGkpoWK1HF6hhy/baike/whfpf%3D360%2C280%2C50/sign=71bcd12444fbfbeddc0c653f1ecdc400/18d8bc3eb13533faa998d335a7d3fd1f41345bfa.jpg")
req = urllib.request.urlopen("https://gss2.bdstatic.com/-fo3dSag_xI4khGkpoWK1HF6hhy/baike/s%3D220/sign=bc88abda1fdfa9ecf92e511552d1f754/023b5bb5c9ea15ce788829cfb8003af33b87b296.jpg")
# req = urllib.request.urlopen("")
# req = urllib.request.urlopen("https://img.alicdn.com/tfs/TB1_.LJe7P2gK0jSZPxXXacQpXa-1880-640.jpg")
img_content = req.read()
with open('4.jpg', 'wb')as f:
f.write(img_content)
if __name__ =='__main__':
main()")
# req = urllib.request.urlopen("https://rpic.douyucdn.cn/live-cover/roomCover/cover_update/2019/09/17/1f067e8b2763c9cd4fd8f3a77ea12522.jpg/webpdy1")
# req = urllib.request.urlopen("https://img.alicdn.com/tfs/TB1_.LJe7P2gK0jSZPxXXacQpXa-1880-640.jpg")
img_content = req.read()
with open('4.jpg', 'wb')as f:
f.write(img_content)
if __name__ =='__main__':
main()
一般的方法是查看别人WEB输出头信息来了解,例如下面的代码:<?php
$host='www.baidu.com'
$fp = @fsockopen($host, 80, $errno, $errstr, 30)
if (!$fp) {
outs("$errstr ($errno)\n")
} else {
fputs($fp, "GET / HTTP/1.1\r\n")
fputs($fp, "Host: $host\r\n")
fputs($fp, "Connection: close\r\n\r\n")
fputs($fp, "\r\n\r\n")
while (!feof($fp)) {
$str=fgets($fp)
if ($str=="\r\n") break
echo $str
}
fclose($fp)
}
?>
上面代码显示出www.baidu.com的服务器类型是:BWS/1.0
事实上,各种查别人操作系统的方法都是不稳妥的,因为那些输出信息是可以通过修改服务器的注册表或者配置文件来修改的。
欢迎分享,转载请注明来源:夏雨云
评论列表(0条)