百木园-与人分享,
就是让自己快乐。

如何用Python实现http客户端和服务器

功能:客户端可以向服务器发送get,post等请求,而服务器端可以接收这些请求,并返回给客户端消息。

 

客户端:

#coding=utf-8
import http.client
from urllib import request, parse


def send_get(url,path,data):#get请求函数
conn = http.client.HTTPConnection(url)
conn.request(\"GET\", path)
r1 = conn.getresponse()
print(r1.status, r1.reason)

data1 = r1.read()
print(data1) #
conn.close()

def send_post(url,path,data,header):#post请求函数
conn = http.client.HTTPConnection(url)#建立连接
conn.request(\"POST\", path,data,header)#用request请求,将信息封装成帧
r1 = conn.getresponse()
print(r1.status, r1.reason)

data1 = r1.read()
print(data1) #
conn.close()
def send_head(url,path,data,header):
conn = http.client.HTTPConnection(url)
conn.request(\"HEAD\", path,data,header)
r1 = conn.getresponse()
print(r1.status, r1.reason)
data1 = r1.headers #
print(data1) #
conn.close()
def send_put(url,path,filedata,header):
conn = http.client.HTTPConnection(url)
conn.request(\"PUT\", path,filedata,header)
r1 = conn.getresponse()
print(r1.status, r1.reason)

data1 = r1.read() #
print(data1)
conn.close()
def send_option(url,path,data,header):
conn = http.client.HTTPConnection(url)
conn.request(\"OPTION\", path,data,header)
r1 = conn.getresponse()
print(r1.status, r1.reason)
data1 = r1.headers #
print(data1) #
conn.close()
def delete_option(url,path,filename,header):
conn = http.client.HTTPConnection(url)
conn.request(\"DELETE\", path, filename, header)
r1 = conn.getresponse()
print(r1.status, r1.reason)

data1 = r1.read() #
print(data1)
conn.close()
if __name__ == \'__main__\':

url=\"localhost:8100\"
data = {
\'my post data\': \'I am client , hello world\',
}
datas = parse.urlencode(data).encode(\'utf-8\')

headers = {\"Content-type\": \"application/x-www-form-urlencoded\",\"Accept\": \"text/plain\"}
while True:
command = input(\"输入请求的命令:\")
if command ==\'get\':
print(\"----------发送get请求:-----------\")
send_get(url,path=\"\",data=\"None\")
elif command==\'post\':
print(\"----------发送post请求-----------\")
send_post(url, path=\"\",data=datas,header=headers)

elif command ==\'put\':
print(\"----------发送put请求-----------\")
file = input(\"输入要发送的文件名:\")
tfile=open(file,encoding=\"UTF-8\",mode=\'r\')
filedatas=tfile.read()
fileheaders = {\"Content-type\": \"text/plain\", \"Accept\": \"text/plain\",\\
\"content-length\":str(len(filedatas))}
send_put(url, path=\"E:/pythonProject2/httpweb/\", filedata=filedatas, header=fileheaders)
elif command==\'head\':
print(\"----------发送head请求:-----------\")
send_head(url, path=\"\", data=datas, header=headers)
elif command==\'option\':
print(\"----------发送option请求:-----------\")
send_option(url,path=\"\",data=datas,header=headers)
elif command==\'delete\':
print(\"----------发送delete请求-----------\")
file = input(\"输入要删除的文件名:\")
fileheaders = {\"Content-type\": \"text/plain\", \"Accept\": \"text/plain\"}
delete_option(url, path=\"E:/pythonProject2/httpweb/\", filename = file, header=fileheaders)
elif command == \'exit\':
break
服务器:
# -*- coding: utf-8 -*-

import socket
import re
import os
import threading
import urllib.parse


def service_client(new_socket):
# 为这个客户端返回数据
# 1.接收浏览器发过来的请求,即http请求
# GET / HTTP/1.1
request = new_socket.recv(1024).decode(\'utf-8\')
request_header_lines = request.splitlines()
print(request_header_lines)
data = request_header_lines[-1]
# ret = re.match(r\'[^/]+(/[^ ]*)\', request_header_lines[0])
ret = list(request_header_lines[0].split(\' \'))[1]
method = list(request_header_lines[0].split(\' \'))[0]
path_name = \"/\"

if method == \'GET\':
if ret:
path = ret
path_name = urllib.parse.unquote(path) # 浏览器请求的路径中带有中文,会被自动编码,需要先解码成中文,才能找到后台中对应的html文件
print(\"请求路径:{}\".format(path_name))

if path_name == \"/\": # 用户请求/时,返回咖啡.html页面
path_name = \"/咖啡.html\"

# 2.返回http格式的数据给浏览器
file_name = \'E:/pythonProject2/httpweb/HTML/\' + path_name
try:
f = open(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()
# 准备发给浏览器的数据 -- header
response = \"HTTP/1.1 200 OK\\r\\n\"
response += \"\\r\\n\"
new_socket.send(response.encode(\"utf-8\"))
new_socket.send(html_content)
# 关闭套接字
if method == \'POST\':
if ret:
path = ret
path_name = urllib.parse.unquote(path) # 浏览器请求的路径中带有中文,会被自动编码,需要先解码成中文,才能找到后台中对应的html文件
print(\"请求路径:{}\".format(path_name))
if path_name == \"/\": # 用户请求/时,返回咖啡.html页面
path_name = \"/咖啡.html\"

# 2.返回http格式的数据给浏览器
file_name = \'E:/pythonProject2/httpweb/HTML/\' + path_name
response = \"HTTP/1.1 200 OK\\r\\n\"
response += \"\\r\\n\"
new_socket.send(response.encode(\"utf-8\"))
new_socket.send(file_name.encode(\"utf-8\")+\' data:\'.encode(\"utf-8\")+data.encode(\"utf-8\"))
if method == \'PUT\':
if ret:
path = ret
path_name = urllib.parse.unquote(path) # 浏览器请求的路径中带有中文,会被自动编码,需要先解码成中文,才能找到后台中对应的html文件
print(\"请求路径:{}\".format(path_name))
if path_name == \"/\": # 用户请求/时,返回咖啡.html页面
path_name = \"/咖啡.html\"

# 2.返回http格式的数据给浏览器
file_name = list(request_header_lines[0].split(\' \'))[1] +\'test.txt\'
content = data.encode(\'utf-8\')
response = \"HTTP/1.1 200 OK\\r\\n\"
response += \"\\r\\n\"
with open(file_name, \'ab\') as f:
f.write(content)
new_socket.send(response.encode(\"utf-8\"))
new_socket.send(\"finish\".encode(\"utf-8\"))
if method==\'HEAD\':
if ret:
path =ret
path_name = urllib.parse.unquote(path)
print(\"请求路径:{}\".format(path_name))
if path_name ==\"/\":
path_name = \"/咖啡.html\"
response = \"HTTP/1.1 200 ok\\r\\n\"
new_socket.send(response.encode(\"utf-8\"))
new_socket.send(str(request_header_lines[1:]).encode(\"utf-8\"))
if method==\'OPTION\':
if ret:
path = ret
path_name = urllib.parse.unquote(path)
print(\"请求路径:{}\".format(path_name))
if path_name == \"/\":
path_name = \"/咖啡.html\"
response = \"HTTP/1.1 200 ok\\r\\n\"
new_socket.send(response.encode(\"utf-8\"))
new_socket.send(\"OPTIONS GET,HEAD,POST,PUT,DELETE\".encode(\"utf-8\"))
if method ==\'DELETE\':
if ret:
path = ret
path_name = urllib.parse.unquote(path) # 浏览器请求的路径中带有中文,会被自动编码,需要先解码成中文,才能找到后台中对应的html文件
print(\"请求路径:{}\".format(path_name))
if path_name == \"/\": # 用户请求/时,返回咖啡.html页面
path_name = \"/咖啡.html\"

deletename = request_header_lines[-1]
# print(path_name+deletename)
os.remove(path_name+deletename)
# 2.返回http格式的数据给浏览器
content = data.encode(\'utf-8\')
response = \"HTTP/1.1 200 OK\\r\\n\"
response += \"\\r\\n\"
# with open(file_name, \'ab\') as f:
# f.write(content)
new_socket.send(response.encode(\"utf-8\"))
new_socket.send(\"finish\".encode(\"utf-8\"))
# 关闭套接字
new_socket.close()


def main():
# 用来完成整体的控制
# 1.创建套接字
tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 2.绑定
tcp_server_socket.bind((\"0.0.0.0\", 8100))
# 3.变为监听套接字
tcp_server_socket.listen(128)
while True:
# 4.等待新客户端的链接
new_socket, client_addr = tcp_server_socket.accept()
# 5.为这个客户端服务
print(\"为\",client_addr,\"服务\")
t = threading.Thread(target=service_client, args=(new_socket,))
t.start()

# 关闭监听套接字
tcp_server_socket.close()


if __name__ == \'__main__\':
main()

来源:https://www.cnblogs.com/subodong/p/16773902.html
本站部分图文来源于网络,如有侵权请联系删除。

未经允许不得转载:百木园 » 如何用Python实现http客户端和服务器

相关推荐

  • 暂无文章