WinError 10049:请求的地址在其上下文中无效

15 投票
3 回答
138864 浏览
提问于 2025-04-18 07:33

我正在尝试在Python中发送一个原始的HTTP请求,并把响应写入一个文件。当我试图绑定到主机的解析IP地址或域名时,出现了这样的错误:

追踪信息(最近的调用在最前面):

File "thingy.py", line 3, in <module>

  soc.bind(('168.62.48.183', 80))

OSError: [WinError 10049] 请求的地址在其上下文中无效

我找到了一条StackOverflow上的问题,它有相同的错误,但没有回答我的问题,因为它是关于一个监听套接字的。以下是我的代码:

from socket import *
soc = socket(AF_INET, SOCK_STREAM)
soc.bind(('168.62.48.183', 80))
soc.send('GET /miners/get?file=BFGMiner-3.99-r.1-win32.zip HTTP/1.1\nUser-Agent:MultiMiner/V3\nHost: www.multiminerapp.com\n')
response = soc.recv()
respfile = open("http-response.txt","w")
respfile.writelines(response)
respfile.close()

3 个回答

0

使用像xamp或wamp这样的第三方软件来创建一个服务器。

然后,

 soc.bind(('server_ip',port_number))
8

首先,你需要把两个设备连接到同一个网络上。然后,对于server.py(或者你想给它起的任何名字)

使用

soc.bind(('', PORT))

而不是

soc.bind(('IP', PORT))
19
from socket import *
soc = socket(AF_INET, SOCK_STREAM)
soc.connect(('168.62.48.183', 80))
soc.send('GET /miners/get?file=BFGMiner-3.99-r.1-win32.zip HTTP/1.1\nUser-Agent:MultiMiner/V3\nHost: www.multiminerapp.com\n')
with open("http-response.txt","w") as respfile:
    response = soc.recv(1024) # <--- Use select.epoll or asyncore instead!
    respfile.writelines(response)

你的代码出错的原因是你试图绑定到一个外部IP地址。
你的机器并不知道这个IP,所以才会出现错误信息。如果你把它改成 127.0.0.1,就可以正常工作了。不过,你还需要加上 .listen(4)ns, na = soc.accept(),然后才能使用 .send(),而你的 soc.recv() 也需要改成 ns.recv(1024)

换句话说,你把客户端的socket和服务器的socket搞混了,你正在尝试绑定一个在本地机器上不存在的IP。

另外要注意soc.recv() 会失败,你需要提供一个缓冲区大小的参数,比如: soc.recv(1024)

Python3:

from socket import *
soc = socket(AF_INET, SOCK_STREAM)
soc.connect(('168.62.48.183', 80))
soc.send(b'GET /miners/get?file=BFGMiner-3.99-r.1-win32.zip HTTP/1.1\nUser-Agent:MultiMiner/V3\nHost: www.multiminerapp.com\n\n') # Note the double \n\n at the end.
with open("http-response.txt","wb") as respfile:
    response = soc.recv(8192)
    respfile.write(response)

这里有两个主要的区别,我们发送的是一个二进制的 GET /miners/.. 字符串,而不是普通字符串。
其次,我们以二进制的形式打开输出文件,因为接收到的数据也是二进制的。

这是因为Python不再为你解码字符串,原因有很多,所以你需要把数据当作二进制处理,或者在过程中手动解码。

你可能应该:

import urllib.request
f = urllib.request.urlopen("http://www.multiminerapp.com/miners/get?file=BFGMiner-3.99-r.1-win32.zip")
print(f.read())

撰写回答