I'm trying to make a program which can automatically connect to a computer in the local network based on the port inputted by the server. then the client, with the same port, tries by using the arp -a command to find every computer in the local network and try to connect to him.
This is the connection Method:
def connect(self):
devices = []
for device in os.popen('arp -a'): devices.append(device)
for ip in devices:
b = re.findall(r"(?:\s|\A)(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})(?=\s|\Z)", ip)
try:
print(b[0])
client_socket = socket.socket()
client_socket.settimeout(3)
client_socket.connect((b[0], self.port))
if type(client_socket) != None:
return client_socket
except Exception as e:
print(e)
I get a pretty weird issue: when I try to be a server on one computer, it works out just fine. However, when I try to switch the roles and be the client on that computer, it suddenly cant find the target computer and when it tries its IP (which I know since I checked the IP address of the computer with ipconfig), it errors out:
[WinError 10061] No connection could be made because the target machine actively refused it
timed out
I'm trying this on 2 different computers and it connects perfectly when i try this with this computer as server. Any help would be appreciated.
Edit: Also, I thought it would be helpful to note that no matter how high i set the timeout to be on the socket, it just waits that amount of time with the correct IP, then says it timed out. This is despite the server binding the port already...
Edit 2.0: Thought about looking at connection errors of the connection program at the other computer... completely different. no 10061 errors, just timing out and list index errors which are perfectly understandable with the nature of the function. Why does it only does the 10061 error on one computer? why when its 2 different computers? I'd like to know.
I ran a scan with Zenmap on my linux server and found the following ports to be open
So I went over my python script below and ran it
But I was given this output!
How would this be the case?
Thanks in advance.
Your try block covers a lot of functions, and except is catching everything and calling it "port closed." At minimum, it could be any of the following situations:
Failed to create a socket.
Failed to connect to the server.
Connected but the server disconnected before you tried to send.
Connected and sent, but server disconnected before you tried to recv
Nmap would consider either of the second two as "open" because the initial handshake succeeded. Your script considers them "closed" instead.
I've got a python script that basically looks something like this:
#############################
# MAIN LOOP
while True:
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
client_socket.connect((url, socketnum))
packet = somedata
client_socket.sendall(packet)
except Exception as e:
# an error occurred
logging.error("An error occurred: {}".format(e))
pass
finally:
logging.info("Closing socket...")
client_socket.close()
time.sleep(70)
What I find is that if this script is run before an internet connection is established on the computer (an embedded Linux system), naturally, when the socket tries to connect, I get "Errno -3 Temporary failure in name resolution". However, if the internet connection is then established, the program STILL cannot resolve the hostname - the only way to get it to work is to restart the python script.
Since this system is not one where I can guarantee the presence of an internet connection at all times, is there anyway to get python to realise that the internet connection now exists and that name resolution information is now available?
EDIT: Some further testing shows that this only happens if the python program is started before any successful internet connection is established on the machine after a boot up. If the python program is started AFTER an internet connection has previously been established on the machine (even if it's subsequently been disconnected), the program operates correctly and will successfully connect to the internet after internet connectivity is restored.
So:
Bootup->Python started->Internet connection established = program doesn't work
Bootup->Internet connection established->Internet disconnected->Python started = program works fine.
Try flushing DNS cache in every iteration.
import os
...
while True:
os.popen('nscd -I hosts',"r")
...
or try service nscd restart command instead.
I want to create a script that finds and locates if a webserver is up an running somewhere inside the local network. My idea was this (not the quickest one). Check all ip's connected to your local network and try to connect to the port that the webserver is listening (let's say it will alwasy listen on 8000). If you find it stop and return the ip. That's the basic idea. I have written my code but not tested it fully yet because my environment has only one Pc at the moment :)....I did run the webserver on my pc though and it id find it. :)
the code looks like that
local_host_ip = socket.gethostbyname(socket.gethostname())
web_client_socket = socket.socket()
try:
if web_client_socket.connect_ex((local_host_ip,8000)) == 0:
print 'Found rhombus server'
web_client_socket.close()
return local_host_ip
except IOError:
pass
for ip in [ip_address for ip_address in socket.gethostbyname_ex(socket.gethostname())[2] if
ip_address != local_host_ip]:
print 'Attempting to find server'
try:
if web_client_socket.connect_ex((local_host_ip,8000)) == 0:
print 'Found rhombus server'
return ip
except IOError:
pass
return 'Rhombus server not found'
I have tried a similar code where but checking if the webserver is listenning in port 8000 (to see if my idea is working) and it did. What i would like to know at first is if there is a quicker and better way, and second, can I get the name of the webserver? I was thinking that even if this code works what happnes if two web servers (different machines each) were running in 8000?
Unless you know beforehand the ip addresses of the hosts in the network (say, have access to the router), I don't think that there is a quickest way than trying each possible ip.
To get the server name you can do a http request for the index, and retrieve the "Server" http header on the response.
My server software says errno99: cannot assign requested address while using an ip address other than 127.0.0.1 for binding.
But if the IP address is 127.0.0.1 it works.
Is it related to namespaces?
I am executing my server and client codes in another python program by calling execfile().
I am actually editing the mininet source code.I edited net.py and inside that I used execfile('server.py') execfile('client1.py') and execfile('client2.py').So as soon as "sudo mn --topo single,3" is called along with the creation of 3 hosts my server and client codes will get executed.I have given my server and client codes below.
#server code
import select
import socket
import sys
backlog = 5
size = 1024
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(("10.0.0.1",9999))
server.listen(backlog)
input = [server]
running = 1
while running:
inputready,outputready,exceptready = select.select(input,[],[])
for s in inputready:
if s == server:
client, address = server.accept()
input.append(client)
else:
l = s.recv(1024)
sys.stdout.write(l)
server.close()
#client code
import socket
import select
import sys
import time
while(1) :
s,addr=server1.accept()
data=int(s.recv(4))
s = socket.socket()
s.connect(("10.0.0.1",9999))
while (1):
f=open ("hello1.txt", "rb")
l = f.read(1024)
s.send(l)
l = f.read(1024)
time.sleep(5)
s.close()
Stripping things down to basics this is what you would want to test with:
import socket
server = socket.socket()
server.bind(("10.0.0.1", 6677))
server.listen(4)
client_socket, client_address = server.accept()
print(client_address, "has connected")
while True:
recvieved_data = client_socket.recv(1024)
print(recvieved_data)
This works assuming a few things:
Your local IP address (on the server) is 10.0.0.1 (This video shows you how)
No other software is listening on port 6677
Also note the basic concept of IP addresses:
Try the following, open the start menu, in the "search" field type cmd and press enter.
Once the black console opens up type ping www.google.com and this should give you and IP address for google. This address is googles local IP and they bind to that and obviously you can not bind to an IP address owned by google.
With that in mind, you own your own set of IP addresses.
First you have the local IP of the server, but then you have the local IP of your house.
In the below picture 192.168.1.50 is the local IP of the server which you can bind to.
You still own 83.55.102.40 but the problem is that it's owned by the Router and not your server. So even if you visit http://whatsmyip.com and that tells you that your IP is 83.55.102.40 that is not the case because it can only see where you're coming from.. and you're accessing your internet from a router.
In order for your friends to access your server (which is bound to 192.168.1.50) you need to forward port 6677 to 192.168.1.50 and this is done in your router.
Assuming you are behind one.
If you're in school there's other dilemmas and routers in the way most likely.
This error will also appear if you try to connect to an exposed port from within a Docker container, when nothing is actively serving the port.
On a host where nothing is listening/bound to that port you'd get a No connection could be made because the target machine actively refused it error instead when making a request to a local URL that is not served, eg: localhost:5000. However, if you start a container that binds to the port, but there is no server running inside of it actually serving the port, any requests to that port on localhost will result in:
[Errno 99] Cannot assign requested address (if called from within the container), or
[Errno 0] Error (if called from outside of the container).
You can reproduce this error and the behaviour described above as follows:
Start a dummy container (note: this will pull the python image if not found locally):
docker run --name serv1 -p 5000:5000 -dit python
Then for [Errno 0] Error enter a Python console on host, while for [Errno 99] Cannot assign requested address access a Python console on the container by calling:
docker exec -it -u 0 serv1 python
And then in either case call:
import urllib.request
urllib.request.urlopen('https://localhost:5000')
I concluded with treating either of these errors as equivalent to No connection could be made because the target machine actively refused it rather than trying to fix their cause - although please advise if that's a bad idea.
I've spent over a day figuring this one out, given that all resources and answers I could find on the [Errno 99] Cannot assign requested address point in the direction of binding to an occupied port, connecting to an invalid IP, sysctl conflicts, docker network issues, TIME_WAIT being incorrect, and many more things. Therefore I wanted to leave this answer here, despite not being a direct answer to the question at hand, given that it can be a common cause for the error described in this question.
Try like this:
server.bind(("0.0.0.0", 6677))
When you bind localhost or 127.0.0.1, it means you can only connect to your service from local.
You cannot bind 10.0.0.1 because it not belong to you, you can only bind ip owned by your computer
You can bind 0.0.0.0 because it means all ip on your computer, so any ip can connect to your service if they can connect to any of your ip
This is not directly answering the question, but is a debugging direction in case above solutions failed.
When you are not on a native environment, let's say you are on a VM or WSL, the inside network might not be transparent to external computer due to NATing. So make sure you can ping the IP from wherever you are trying to bind. If not, then consider switching to the correct environment or consider network bridging.
If you are looking for a WSL2 specific solution, you may try this link:
Bridging WSL2 network adapter with Windows
In Virtual Box you may change Network Adapter -> Attached To: Bridged Adapter.
The other consideration is if you are trying to bind to a port <1023 you need admin privilege.
This was what I need on a remote VM:
jupyter notebook --ip=0.0.0.0 --port=8888
Copied from here