Python套接字客户端Post参数
首先让我澄清一下我不想使用更高级别的API,我只想使用套接字编程 我已经编写了以下程序来使用POST请求连接到服务器Python套接字客户端Post参数,python,sockets,http,post,Python,Sockets,Http,Post,首先让我澄清一下我不想使用更高级别的API,我只想使用套接字编程 我已经编写了以下程序来使用POST请求连接到服务器 import socket import binascii host = "localhost" port = 9000 message = "POST /auth HTTP/1.1\r\n" parameters = "userName=Ganesh&password=pass\r\n" contentLength = "Content-Length: " + str
import socket
import binascii
host = "localhost"
port = 9000
message = "POST /auth HTTP/1.1\r\n"
parameters = "userName=Ganesh&password=pass\r\n"
contentLength = "Content-Length: " + str(len(parameters))
contentType = "Content-Type: application/x-www-form-urlencoded\r\n"
finalMessage = message + contentLength + contentType + "\r\n"
finalMessage = finalMessage + parameters
finalMessage = binascii.a2b_qp(finalMessage)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
s.sendall(finalMessage)
print(s.recv(1024))
我在线查看了POST请求是如何创建的
不知何故,参数没有传递到服务器。我是否必须在请求之间添加或删除“\r\n”
提前感谢,,
当做
Ganesh.这一行
finalMessage=binascii.a2b_qp(finalMessage)
肯定是错误的,因此您应该完全删除该行,另一个问题是内容长度之后没有新行丢失。在这种情况下,发送到套接字的请求是(我在这里将CR
和LF
字符显示为\r\n
,但为了清晰起见,还将行拆分):
因此,这显然对web服务器没有多大意义
但是,即使在添加新行并删除a2b_qp
之后,问题仍然是您不在那里;请求必须具有HTTP/1.1(RFC 2616 14.23)的主机头:
客户端必须在所有HTTP/1.1请求中包含主机头字段
信息。如果请求的URI不包括Internet主机名
对于所请求的服务,则主机标头字段必须为
给定一个空值。HTTP/1.1代理必须确保
它转发的请求消息确实包含适当的主机头
标识代理请求的服务的字段全部
基于Internet的HTTP/1.1服务器必须响应400(错误请求)
任何缺少主机头的HTTP/1.1请求消息的状态代码
字段。
此外,您不支持分块请求和持久连接、keepalives或其他任何操作,因此必须执行连接:关闭
(RFC 2616 14.10):
不支持持久连接的HTTP/1.1应用程序必须
在每条消息中包括“关闭”连接选项
因此,任何HTTP/1.1
服务器如果在没有Host:
头的情况下仍能正常响应您的消息,也会被破坏
这是您应随该请求发送到套接字的数据:
POST /auth HTTP/1.1\r\n
Content-Type: application/x-www-form-urlencoded\r\n
Content-Length: 29\r\n
Host: localhost:9000\r\n
Connection: close\r\n
\r\n
userName=Ganesh&password=pass
请注意,您不再在正文中添加\r\n
(因此正文的长度为29)。此外,您还应该阅读响应,以找出您得到的错误
在Python 3上,工作代码会说:
host = "localhost"
port = 9000
headers = """\
POST /auth HTTP/1.1\r
Content-Type: {content_type}\r
Content-Length: {content_length}\r
Host: {host}\r
Connection: close\r
\r\n"""
body = 'userName=Ganesh&password=pass'
body_bytes = body.encode('ascii')
header_bytes = headers.format(
content_type="application/x-www-form-urlencoded",
content_length=len(body_bytes),
host=str(host) + ":" + str(port)
).encode('iso-8859-1')
payload = header_bytes + body_bytes
# ...
socket.sendall(payload)
下面是代码示例:@Antti Haapala,非常感谢。这解决了我的问题。请原谅我的知识。还有一件事,调用binascii.a2b_qp()是必要的,因为套接字不接收字符串作为输入。
host = "localhost"
port = 9000
headers = """\
POST /auth HTTP/1.1\r
Content-Type: {content_type}\r
Content-Length: {content_length}\r
Host: {host}\r
Connection: close\r
\r\n"""
body = 'userName=Ganesh&password=pass'
body_bytes = body.encode('ascii')
header_bytes = headers.format(
content_type="application/x-www-form-urlencoded",
content_length=len(body_bytes),
host=str(host) + ":" + str(port)
).encode('iso-8859-1')
payload = header_bytes + body_bytes
# ...
socket.sendall(payload)