Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.2k views
in Technique[技术] by (71.8m points)

python - WinError 10049: The requested address is not valid in its context

I am trying to make a raw HTTP request in Python and write the response to a file. When I try to bind to the resolved IP Address or domain of the host I get this:

Traceback (most recent call last):

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

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

OSError: [WinError 10049] The requested address is not valid in its context

I found a StackOverflow question that had the identical error, but it did not answer my question because it was for a listening socket. Here is my code:

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
User-Agent:MultiMiner/V3
Host: www.multiminerapp.com
')
response = soc.recv()
respfile = open("http-response.txt","w")
respfile.writelines(response)
respfile.close()
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)
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
User-Agent:MultiMiner/V3
Host: www.multiminerapp.com
')
with open("http-response.txt","w") as respfile:
    response = soc.recv(1024) # <--- Use select.epoll or asyncore instead!
    respfile.writelines(response)

The reason for why your code fails tho is because you're trying to bind to an external IP.
Your machine is not aware of this IP hence the error message, if you'd change it to say 127.0.0.1 it would work, but then again you would need a .listen(4) and ns, na = soc.accept() before utelizing .send() and your soc.recv() would need to be ns.recv(1024).

In other words, you mixed up client sockets with server sockets and you're binding to a IP not present on the local machine.

Also note: soc.recv() will fail, you need a buffer-size argument like so: 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
User-Agent:MultiMiner/V3
Host: www.multiminerapp.com

') # Note the double 

 at the end.
with open("http-response.txt","wb") as respfile:
    response = soc.recv(8192)
    respfile.write(response)

There's two major differences, we send a binary GET /miners/.. string rather than a standard string. Secondly we open the output-file in a binary form because the data recieved will also be in binary form..

This is because Python no longer decodes the string for you because of a number of reasons, so you need to either treat the data as binary or manually decode it along the way.

You should probably:

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...