Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/338.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python套接字客户端Post参数_Python_Sockets_Http_Post - Fatal编程技术网

Python套接字客户端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

首先让我澄清一下我不想使用更高级别的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(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)