Attempting to reconnect after a connection was refused - Python - python

I am trying to create a script that will, on error, attempt to reconnect again. But even after the receiving server has been started it still will not connect
send_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
while True:
try: #Cant get it to make connection after retrying
send_sock.connect((ip, port)) #always throws Con Refused when tryed
break
except socket.error:
print "Connection Failed, Retrying.."
time.sleep(1)
send_sock.send("hi")
edit: Corrected "try:" typo

Had this same issue myself, once I had worked it out it was actually quite a simple solution, all you need to do is create the send_sock before every connection attempt. Not sure why this fixes it but it does for me. Hope it does for you too.
while True:
try:#moved this line here
send_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
send_sock.connect((ip, port)) #no longer throws error
break
except socket.error:
print "Connection Failed, Retrying.."
time.sleep(1)
send_sock.send("hi")

Python socket will give you a error that should help with debugging your problem. For your example.
try:
send_sock.connect((ip, port))
except socket.error as error:
print("Connection Failed **BECAUSE:** {}").format(error)
Second of all you should almost never use while true: [...] as its just going to cause all sorts of problems. In this case you could put in a counter and loop on that break after X attempts.
While counter < 100:
try:
send_sock.connect((ip, port))
except socket.error as error:
print("Connection Failed **BECAUSE:** {}").format(error)
print("Attempt {} of 100").format(counter)
counter += 1
Check out the Python Docs on socket exceptions for more info.

Related

shutdown() and close() not found in 'None'

I'm using python 3.8, and trying to learn to code for networking; I've seen some examples from 2014 with code for a port scanner, which is defines the port scanning function like this:
def pscan(port):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
con = sock.connect((target, port))
with print_lock:
print("Port:",port,"is open.")
con.shutdown()
con.close()
When I implement this in pycharm I see the message:
"Cannot find reference 'shutdown' in 'None'
and
"Cannot find reference 'close' in 'None'
The code runs, but never seems to stop... I am guessing that it is due to not properly closing the socket.
Can anyone educate me as to where my error is?
connect doesn't return anything.
I think you want this:
def pscan(port):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
sock.connect((target, port))
with print_lock:
print("Port:",port,"is open.")
sock.shutdown()
sock.close()
Also, no need to call shutdown if you're going to immediately call close afterwards.

Network checker giving false negatives python

This code is able to detect whether the internet is disconnected or connected, and works mostly as I've tested it. The problem is occasionally it says internet disconnected and right after that it says internet connected. This has happened many times while I'm browsing the web, watching videos or whatever, the point being I know the internet is working.
I know the code's a bit of a mess. What's causing these false disconnects?
import win32com.client as w
import socket
s = w.Dispatch("SAPI.SpVoice")
try:
socket.setdefaulttimeout(5)
socket.socket(socket.AF_INET, socket.SOCK_STREAM).connect(("8.8.8.8", 53))
a = True
except Exception:
a = False
pass
while a == True:
while True:
try:
socket.setdefaulttimeout(5)
socket.socket(socket.AF_INET, socket.SOCK_STREAM).connect(("8.8.8.8", 53))
s.Speak("Internet connected")
break
except Exception:
continue
while True:
try:
socket.setdefaulttimeout(5)
socket.socket(socket.AF_INET, socket.SOCK_STREAM).connect(("8.8.8.8", 53))
continue
except Exception:
s.Speak("Internet disconnected")
break
while a == False:
while True:
try:
socket.setdefaulttimeout(5)
socket.socket(socket.AF_INET, socket.SOCK_STREAM).connect(("8.8.8.8", 53))
continue
except Exception:
s.Speak("Internet disconnected")
break
while True:
try:
socket.setdefaulttimeout(5)
socket.socket(socket.AF_INET, socket.SOCK_STREAM).connect(("8.8.8.8", 53))
s.Speak("Internet connected")
except Exception:
continue
You're connecting to google's DNS server at a rate of about 100 times per second, at least on my machine. I wouldn't be surprised if they occasionally refuse your connections, but I'm not willing to test this theory. Perhaps your machine is running out of ports at this rate? I have no idea how windows TCP stack would handle something like this.
Try adding a sleep into all of your loops to make sure you're not hammering them - testing your connection every couple of seconds should be fine.
Also, your original question is "Why is the socket failing to connect?" Well, catch the exception, and print so you'll know (or say it out loud :) )

Problems with socketing in IDLE

I'm trying to get a small socket communication set up on my own machine for testing purposes, but I keep getting errors like "[Errno 10053] An established connection was aborted by the software in your host machine" and "[Errno 10054] An existing connection was forcibly closed by the remote host"
The code for the server is
import socket, threading, Queue
class PiConn(threading.Thread, object):
def __init__(self, input_queue, output_queue):
threading.Thread.__init__(self)
self.input_queue = input_queue
self.output_queue = output_queue
self.HOST = ''
self.PORT = 8888
self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
try:
self.s.bind((self.HOST, self.PORT))
except socket.error, msg:
print "Binding socket failed, error message: " + msg[1]
def run(self):
self.s.listen(5)
while True:
try:
#trying to accept data
conn, addr = self.s.accept()
print "Connected to", addr
data = conn.recv(4096)
self.input_queue.put(data)
except Exception as e:
print e, "when trying to accept data"
break
try:
output = self.output_queue.get(False)
self.s.sendall(output)
print "Sent", output
except Queue.Empty:
pass
except socket.error as e:
print e, "when trying to send data"
input_queue = Queue.Queue()
output_queue = Queue.Queue()
conn = PiConn(input_queue, output_queue)
conn.start()
while True:
output_queue.put("This is sent by server")
try:
print input_queue.get(False)
except Queue.Empty:
pass
The code for the client is
import socket, threading, Queue
class GUIConn(threading.Thread, object):
def __init__(self, input_queue, output_queue):
threading.Thread.__init__(self)
self.input_queue = input_queue
self.output_queue = output_queue
self.PORT = 8888
self.PI_IP = "127.0.0.1"
try:
#Creates a socket
self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
except socket.error, msg:
print 'Socket creating failed, error message:' + str(msg[1])
self.s.connect((self.PI_IP, self.PORT))
def run(self):
while True:
try:
#Trying to send data
output = self.output_queue.get(False)
self.s.sendall(output)
except Queue.Empty:
pass
except socket.error as e:
print e
try:
#trying to accept data
data = self.s.recv(4096)
self.input_queue.put(data)
except Exception as e:
print e
break
input_queue = Queue.Queue()
output_queue = Queue.Queue()
conn = GUIConn(input_queue, output_queue)
conn.start()
while True:
output_queue.put("This is sent by client")
try:
print input_queue.get(False)
except Queue.Empty:
pass
To test it, I start 2 IDLE shells, run the server, and then the client.
Any clue as to what I'm doing wrong? I'm fairly new at sockets, and I've been struggling with this all day.
Thanks in advance!
Your initial problem is caused by known issues IDLE has when working with threads.
See here and here for example.
I'm not aware of any workaround. Try running your code from terminal instead.
As to the other errors you're getting, if you post them, we can try and assist.
warning, big wall of text, read all of it before commenting
there is a huge number of problem with this small amount of code
first, the most obvious is the 'busy' loops that will use up all 100% of the cpu, not only that, it will also slowly use up all the ram as well cause you set the blocking for the queue.get to be False
you could have set it to True and it would have waited until there something and once it get that, it would loop back to the top and put another one of "This is sent by client" thus solving both the busy loop and ram usage problem
while True:
output_queue.put("This is sent by client")
try:
print input_queue.get(False) # here
except Queue.Empty:
pass
second, the way you reply/send data from the server to the client isn't through the main listening socket but the socket that is return from the self.s.accept()
so self.s.sendall(output) in the server should have been conn.sendall(output)
third, in the client code, there a chance that self.output_queue.get(False) would error with Queue.Empty and thus pass using the try and except and ended up in the blocking recv
and both the server and client would both be listening and waiting for each other to send something
fourth, self.s.accept() is blocking, after one loop in the server, it would be stuck waiting for another client while the client would send the data then end up waiting for some data
lastly, about those error you said, i can't reproduce them at all, if i have to guess, i say those error are cause by your firewall or the server isn't running (fail to bind) or something else, see here: No connection could be made because the target machine actively refused it
also, you could try a different port and maybe the first two example on this site to check if there is something weird causing problem, if those example doesn't work then there is a problem with your computer, https://docs.python.org/release/2.5.2/lib/socket-example.html

What is wrong with the statement socket.sendall(message) in python 3.3?

Hi I am trying to learn sockets in python 3.3 but have an issue sending data to the remote server. Has the command be changed in python 3.3 or am I just doing it wrong. Please find the code below so you can see the problem. Would prefer a simple splution like change s.sendall to s.send or something. If not possible no worries
import socket
import sys
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error:
print("Failed to create a socket")
print("Socket created")
host = ("www.google.com")
port = 80
try:
remote_ip = socket.gethostbyname(host)
except socket.gaierror:
print("Hostname could not be found, exiting finding socket")
sys.exit()
print("Ip adress of",host,"is",remote_ip)
s.connect((remote_ip, port))
print("Socket connected to",host,"on ip", remote_ip)
message = "GET / HTTP/1.1/r/n/r/n"
try:
s.send(message)
except socket.error:
print("Failed")
sys.exit
print("Message send successful")
reply = s.recv(4096)
print(reply)
s.close()
First, you used slash where you meant to use backslash. Try this instead:
message = "GET / HTTP/1.1\r\n\r\n"
Second, yes, the send() call did change a little. Try this:
s.send(message.encode('utf-8'))

Understanding Error Codes in Python and Using Meanful Error Names

I understand the basic try: except: finally: syntax for pythons error handling. What I don't understand is how to find the proper error names to make readable code.
For example:
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
s.settimeout(60)
char = s.recv(1)
except socket.timeout:
pass
so if socket raises a timeout, the error is caught. How about if I am looking for a connection refused. I know the error number is 10061. Where in the documentation do I look to find a meaning full name such as timeout. Would there be a similar place to look for other python modules? I know this is a newbie question but I have been putting in error handling my my code for some time now, without actually knowing where to look for error descriptions and names.
EDIT:
Thanks for all your responses.
would
except socket.error, exception:
if exception.errno == ETIMEDOUT:
pass
achieve the same result as
except socket.timeout:
pass
To achieve what you want, you'll have to grab the raised exception, extract the error code stored into, and make some if comparisons against errno codes:
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
s.settimeout(60)
char = s.recv(1)
except socket.error, exception:
if exception.errno == errno.ECONNREFUSED:
# this is a connection refused
# or in a more pythonic way to handle many errors:
{
errno.ECONNREFUSED : manage_connection_refused,
errno.EHOSTDOWN : manage_host_down,
#all the errors you want to catch
}.get(exception.errno, default_behaviour)()
except socket.timeout:
pass
with :
def manage_connection_refused():
print "Connection refused"
def manage_host_down():
print "Host down"
def default_behaviour():
print "error"
You will get an error with an errno, which is described in the errno documentation. 10061 is only valid for WinSock.
According to socket, socket.error values are defined in the errno module.

Categories

Resources