到目前为止,这就是我所拥有的,我所到过的每个地方都说此代码应该可以,但不能。
import socket
mysock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
mysock.connect(('data.pr4e.org', 80))
mysock.send(b'GET http://data.pr4e.org/romeo.txt HTTP/1.0\n\n')
while True:
data = mysock.recv(512)
if ( len(data) < 1 ) :
break
print (data)
mysock.close()
这是我得到的输出:
b'HTTP/1.1 400 Bad Request\r\nDate: Sun, 25 Nov 2018 19:23:51 GMT\r\nServer:
Apache/2.4.18 (Ubuntu)\r\nContent-Length: 308\r\nConnection:
close\r\nContent-Type: text/html; charset=iso-8859-1\r\n\r\n<!DOCTYPE HTML
PUBLIC "-//IETF//DTD HTML 2.0//EN">\n<html><head>\n<title>400 Bad
Request</title>\n</head><body>\n<h1>Bad Request</h1>\n<p>Your browser sent a
request that this server could not understand.<br
/>\n</p>\n<hr>\n<address>Apache/2.4.18 (Ubuntu) Server at do1.dr-chuck.com
Port 80</address>\n</body></html>\n'
这是示例说的我应该回来的话:
HTTP/1.1 200 OK
Date: Sun, 14 Mar 2010 23:52:41 GMT
Server: Apache
Last-Modified: Tue, 29 Dec 2009 01:31:22 GMT
ETag: "143c1b33-a7-4b395bea"
Accept-Ranges: bytes
Content-Length: 167
Connection: close
Content-Type: text/plain
But soft what light through yonder window breaks
It is the east and Juliet is the sun
Arise fair sun and kill the envious moon
Who is already sick and pale with grief
为什么我没有得到相同的输出?
答案 0 :(得分:0)
从某种意义上说,您的代码能够正常工作,因为它可以成功地将请求发送到服务器,并且您确实获得了有效的结果。您可以看到错误消息本身来自服务器 。
但是您没有获得 expected 结果,因此确实存在问题。在浏览器中直接打开http://data.pr4e.org/romeo.txt可以正常工作,因此让我们进一步看一下,例如400 error header with sockets之类的问题,它们处理的问题几乎相同。
经过一些试验,看来Web服务器需要 Microsoft Windows样式的行尾:\r
和 \n
。像您尝试的那样,仅\n
不起作用–您会得到该错误。只是\r
会使服务器无限期地等待(或者说“相当长,而且肯定比我准备等待该实验更长的时间”)。
因此,这种简单的修改使您的原始程序可以工作:
mysock.send(b'GET http://data.pr4e.org/romeo.txt HTTP/1.0\r\n\r\n')
并在几个标题之后返回这首诗:
... But soft what bytes through yonder port breaks
It is a request and Http is the Sun ...
(可以稍作释义)
在某些操作系统上(Microsoft Windows是我所知道的唯一操作系统),行尾\n
的标准代码会自动 扩展为\r\n
。因此,可以合理地假设您的工作示例代码是在Windows机器上编写和测试的,并且其编写者从未知道(或担心)Apache服务器期望这种显式的行尾。