Hello everyone, I am implementing a bittorrent client and i have hit a roadblock.
Here is my code to get the peer list from a particular tracker which only deals in ipv6.
tracker = "udp://tracker.birkenwald.de:6969/announce"
parse = urlparse(tracker)
ip, port = (socket.getaddrinfo(parse.hostname, parse.port, 0, 0, socket.SOL_TCP))[0][4][0], parse.port
#ip, port = 2001:1b10:1000:8101:0:242:ac11:2,6969
sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
sock.sendto(tracker_connection.bytestringForConnecting(), (ip, port))
#bytestringForConnecting() is a function for getting the byte version as written in the protocol.
Getting the following error
Traceback (most recent call last):
File "main.py", line 17, in <module>
t.get_peer_list()
File "/home/aditya/Desktop/CN/CN PROJECT/tracker.py", line 21, in get_peer_list
self.udp_request(url)
File "/home/aditya/Desktop/CN/CN PROJECT/tracker.py", line 64, in udp_request
sock.sendto(tracker_connection.bytestringForConnecting(), (ip, port))
socket.gaierror: [Errno -9] Address family for hostname not supported
The python socket documentation says that AF_INET6 addresses must be passed as a tuple of 4 values. If you pass a 2-tuple it'll be interpreted as AF_INET (IPv4) address.
Related
I have a very simple Python code for bind or connect to a port. it works without any error on Ubuntu and CentOs but I have an error on Windows 10. I turned off the firewall and antivirus but it didn't help.
my code:
import socket
port = 9999
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = socket.gethostname()
try:
s.connect((host,port))
except:
s.bind((host, port))
s.listen(1)
print("I'm a server")
clientsocket, address = s.accept()
else:
print("I'm a client")
error on windows 10:
Traceback (most recent call last):
File "win.py", line 11, in <module>
s.connect((host,port))
ConnectionRefusedError: [WinError 10061] No connection could be made because the target machine actively refused it
During the handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "win.py", line 13, in <module>
s.bind((host, port))
OSError: [WinError 10022] An invalid argument was supplied
Edit:
I found my problem is in Try... Except part, if I put this code in two files my problem will solve. But Why? try except don't work correctly in Windows?
The connect() fails because there is no server socket listening at (host,port).
The bind() fails because you can't bind to a hostname, only to an IP address. Unless you want to listen on just a specific network interface, you should bind to 0.0.0.0 to listen on all interfaces.
import socket
PORT = 5050
SERVER = "Insert my public IPV4 address here"
ADDR = (SERVER, PORT)
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(ADDR) #here is the line I get the error for
The error says:
Traceback (most recent call last):
File "The Directory", line 15, in <module>
server.bind(ADDR)
OSError: [WinError 10049] The requested address is not valid in its context
Can I not use my IPV4 to make the server public?
If not then what do I use?
I am trying to connect and send data from my laptop to my Android phone via Bluetooth. I am using PyBluez library for that. When I am trying to call 'connect' method of BluetoothSocket:
sock=BluetoothSocket( RFCOMM )
sock.connect((host, port))
it always gives me the same error:
Traceback (most recent call last):
File "rfcomm-client.py", line 41, in <module>
sock.connect((host, port))
File "<string>", line 5, in connect
bluetooth.btcommon.BluetoothError: (22, 'Invalid argument')
As I understood from docs and examples, the type of host should be String, and port should be int. That I checked.
I also checked the validity of both port and host, and already paired my devices.
Could anybody help me with this issue?
I was trying to understand how non-blocking sockets work ,so I wrote this simple server in python .
import socket
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('127.0.0.1',1000))
s.listen(5)
s.setblocking(0)
while True:
try:
conn, addr = s.accept()
print ('connection from',addr)
data=conn.recv(100)
print ('recived: ',data,len(data))
except:
pass
Then I tried to connect to this server from multiple instances of this client
import socket
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('127.0.0.1',1000))
while True:
continue
But for some reason putting blocking to 0 or 1 dose not seem to have an effect and server's recv method always block the execution.
So, dose creating non-blocking socket in python require more than just setting the blocking flag to 0.
setblocking only affects the socket you use it on. So you have to add conn.setblocking(0) to see an effect: The recv will then return immediately if there is no data available.
You just need to call setblocking(0) on the connected socket, i.e. conn.
import socket
s = socket.socket()
s.bind(('127.0.0.1', 12345))
s.listen(5)
s.setblocking(0)
>>> conn, addr = s.accept()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib64/python2.7/socket.py", line 202, in accept
sock, addr = self._sock.accept()
socket.error: [Errno 11] Resource temporarily unavailable
# start your client...
>>> conn, addr = s.accept()
>>> conn.recv() # this will hang until the client sends some data....
'hi there\n'
>>> conn.setblocking(0) # set non-blocking on the connected socket "conn"
>>> conn.recv()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
socket.error: [Errno 11] Resource temporarily unavailable
https://docs.python.org/3/library/socket.html#socket.setdefaulttimeout
You can use s.setdefaulttimeout(1.0) to apply all connection sockets as default.
The following code runs a socket server on a thread. The client socket sends 'client: hello' to the server, and the server socket receives and replies 'server: world'.
import socket
import threading
def server():
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(('127.0.0.1', 12345))
sock.listen(1)
req, addr = sock.accept()
print req.recv(1024)
req.sendall('server: world')
def client():
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(('127.0.0.1', 12345))
sock.sendall('client: hello')
print sock.recv(1024)
def main():
t = threading.Thread(target=server)
t.start()
client()
if __name__ == '__main__':
main()
It runs ok as expected the first time, but from the second time, if you do not wait for a good few seconds for the server to release the socket, and if you try this on a Linux machine or Mac (Windows do not get it somehow) you will run into this error:
Traceback (most recent call last):
File "socket_send_receive.py", line 24, in <module>
main()
File "socket_send_receive.py", line 21, in main
client()
File "socket_send_receive.py", line 14, in client
sock.connect(('127.0.0.1', 12345))
File "<string>", line 1, in connect
socket.error: [Errno 111] Connection refused
Exception in thread Thread-1:
Traceback (most recent call last):
File "/home/cxuan/python/2.6/lib/python2.6/threading.py", line 532, in __bootstrap_inner
self.run()
File "/home/cxuan/python/2.6/lib/python2.6/threading.py", line 484, in run
self.__target(*self.__args, **self.__kwargs)
File "socket_send_receive.py", line 6, in server
sock.bind(('127.0.0.1', 12345))
File "<string>", line 1, in bind
error: [Errno 98] Address already in use
I am looking for some insight into why this is happening and if it is possible to be genuinely resolved or what best practice should be adopted.
I know already using this option can be a workaround thanks to the other posts here on stackoverflow.
socket.SO_REUSEADDR
When a socket is closed, it ends up in a state called STATE_WAIT (see this diagram). While the socket is in this state, no one else can use the same address (ip-number/port pair) unless the SO_REUSEADDR option is set on the socket.
See e.g. the Wikipedia article on TCP for more information about how TCP works and the different states.