功能:客户端可以向服务器发送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()

如何用Python实现http客户端和服务器的更多相关文章

  1. 【转】Linux环境搭建FTP服务器与Python实现FTP客户端的交互介绍

    Linux环境搭建FTP服务器与Python实现FTP客户端的交互介绍 FTP 是File Transfer Protocol(文件传输协议)的英文简称,它基于传输层协议TCP建立,用于Interne ...

  2. HTTPS请求HTTP接口被浏览器阻塞,python实现websocket客户端,websocket服务器,跨域问题,dwebsocket,https,拦截,服务端

    HTTPS请求HTTP接口被浏览器阻塞,python实现websocket客户端,websocket服务器,跨域问题,dwebsocket,https,拦截,服务端 发表时间:2020-03-05 1 ...

  3. 利用Python中SocketServer 实现客户端与服务器间非阻塞通信

    利用SocketServer模块来实现网络客户端与服务器并发连接非阻塞通信 版权声明 本文转自:http://blog.csdn.net/cnmilan/article/details/9664823 ...

  4. 【python】网络编程-SocketServer 实现客户端与服务器间非阻塞通信

    利用SocketServer模块来实现网络客户端与服务器并发连接非阻塞通信.首先,先了解下SocketServer模块中可供使用的类:BaseServer:包含服务器的核心功能与混合(mix-in)类 ...

  5. 如何用python抓取js生成的数据 - SegmentFault

    如何用python抓取js生成的数据 - SegmentFault 如何用python抓取js生成的数据 1赞 踩 收藏 想写一个爬虫,但是需要抓去的的数据是js生成的,在源代码里看不到,要怎么才能抓 ...

  6. 搭建简易的c语言与python语言CGI和Apache服务器的开发环境

    搭建简易的c语言CGI和Apache服务器的开发环境 http://www.cnblogs.com/tt-0411/archive/2011/11/21/2257203.html python配置ap ...

  7. python网络-TFTP客户端开发(25)

    一. TFTP协议介绍 TFTP(Trivial File Transfer Protocol,简单文件传输协议) 是TCP/IP协议族中的一个用来在客户端与服务器之间进行简单文件传输的协议 特点: ...

  8. 基于Python的ModbusTCP客户端实现

    Modbus协议是由Modicon公司(现在的施耐德电气Schneider Electric)推出,主要建立在物理串口.以太网TCP/IP层之上,目前已经成为工业领域通信协议的业界标准,广泛应用在工业 ...

  9. WEB客户端和服务器

    # encoding=utf-8 #python 2.7.10 #xiaodeng #HTTP权威指南 #HTTP协议:超文本传输协议是在万维网上进行通信时所使用的协议方案. #WEB客户端和服务器: ...

  10. 聊天室(C++客户端+Pyhton服务器)2.基本功能添加

    根据之前的框架添加新的功能 登录 点击相关按钮 // 登录按钮的响应void CMainDialog::OnBnClickedLogin(){ // 1. 获取用户输入的数据 UpdateData(T ...

随机推荐

  1. SpringBoot3正式版将于11月24日发布:都有哪些新特性?

    从 2018 年 2 月 28 号发布 Spring Boot 2.0 版本开始,整个 2.X 版本已经经过了 4 年多的时间,累计发布了 95 个不同的版本,而就在前不久,2.X 系列的也已经迎来了 ...

  2. 论文翻译:2022_DeepFilterNet2: Towards Real-Time Speech Enhancement On Embedded Devices For Fullband Audio

    博客地址:凌逆战 论文地址:DeepFilternet2: 面向嵌入式设备的全波段音频实时语音增强 论文代码:https://github.com/Rikorose/DeepFilterNet 引用格 ...

  3. Java外包程序员的技术出路

    学习的两个目的: 应付面试 应付工作(解决问题) 首先要明白学习的目的,不同阶段,不同技术的学习目的是不一样的. 有些技术,仅仅是应用级别的,有些技术是原理级别的(主要还是应试).所以不同技术.不同时 ...

  4. CentOS Linux 的安装

    CentOS Linux 的安装 作者:Grey 原文地址: 博客园:CentOS Linux 的安装 CSDN:CentOS Linux 的安装 说明 本安装说明是基于 Windows 10 下 V ...

  5. 【重难点】函数式接口、函数式编程、匿名内部类、Lambda表达式、语法糖

    一.函数式接口 1.概念 仅有一个抽象方法的接口 适用于函数式编程(Lambda表达式) 常见:Runnable.Comparator<>.生产型接口Producer的get方法.消费型接 ...

  6. Mybatis-Plus 对 json 的存储使用支持

    Mybatis-Plus 对 json 的存储使用支持 场景分析: 随着数据库对字段类型支持的多元化,json 类型的存储已成为多场景高频使用的字段类型.而 MySql.postgrpSql 等都支持 ...

  7. ChatGPT 加图数据库 NebulaGraph 预测 2022 世界杯冠军球队

    一次利用 ChatGPT 给出数据抓取代码,借助 NebulaGraph 图数据库与图算法预测体坛赛事的尝试. 作者:古思为 蹭 ChatGPT 热度 最近因为世界杯正在进行,我受到这篇 Cambri ...

  8. 自己动手基于 Redis 实现一个 .NET 的分布式锁

    分布式锁的核心其实就是采用一个集中式的服务,然后多个应用节点进行抢占式锁定来进行实现,今天介绍如何采用Redis作为基础服务,实现一个分布式锁的类库,本方案不考虑 Redis 集群多节点问题,如果引入 ...

  9. python虚拟环境和venv的使用

    目录 1.环境与虚拟环境 2.查看帮助 3.--system-site-package 命令 4.创建虚拟环境 5.激活/关闭虚拟环境 6.保存和复制虚拟环境 7.改变虚拟环境所指向的真实python ...

  10. 金融科技 DevOps 的最佳实践

    随着软件技术的发展,越来越多的企业已经开始意识到 DevOps 文化的重要价值.DevOps 能够消除改变公司业务开展方式,并以更快的速度实现交付,同时创建迭代反馈循环以实现持续改进.而对于金融科技( ...