I know there are other posts that are similar to mine but i did not get anything useful from those posts so here i go.
I have this code that i use:
def startElection():
index = vesselList.index(getmyip())
if index >= (len(vesselList)-1):
neighbour = vesselList[0]
else:
neighbour = vesselList[index+1]
try:
socket = openconn(neighbour, destport, localip=None, localport=None, timeout = 5)
socket.send(iD)
socket.close()
except socket.error, exc:
print "Caught exception socket.error : %s" % exc
I get the error:
Exception (with type 'exceptions.UnboundLocalError'): local variable 'socket' referenced before assignment
I have tried changing the name of the socket. I have tried writing socket= None before the try method. Im not really sure why this is happening.
******** EDIT 1 ********
I have this code that is almost identical to the one i showed you guys first. This code below me works perfectly fine to run, no errors. When i uncomment the function call made to startElection() the code below me runs perfectly.
#Start the for loop to send the new word to all the vessels in our vesselList.
destport = 63166
for destHost in vesselList:
if destHost != getmyip(): #Obviously we wont be needing to send it to the vessel it was made in.
try:
soocket = openconn(destHost, destport, localip=None, localport=None, timeout = 5)
soocket.send(userMSG)
soocket.close()
except soocket.error, exc:
print "Caught exception socket.error : %s" % exc
You're using socket as a variable name and as a type.
The socket.error type is on the socket class. Because you've declared that socket is a variable, the runtime has probably created the local variable name with out a reference and then tried to use it to set-up the exception handler.
Change the name of the variable and the problem should go away.
In my situation was that the port number was wrongly defined. A quick change on that fixed my problem!
Related
Using python 3.6.8, I have the following code
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.settimeout(20)
s.connect(host, port)
As I understand it, using with as shown instead of a try except block better handles the error condition that occurs if opening the socket (s.connect()) fails. How so? In the code as shown, if s.connect() times out, will it print a message? My main question is, can I detect that it timed out, e.g. to run some code if a timeout occurs? I want to be able to do that from within the with block without using try. I read this example
with opened_w_error("/etc/passwd", "a") as (f, err):
if err:
print "IOError:", err
else:
f.write("guido::0:0::/:/bin/sh\n")
But that doesn't detect the type of error. I read this as well
try:
with ContextManager():
BLOCK
except InitError: # raised from __init__
...
except AcquireResourceError: # raised from __enter__
...
except ValueError: # raised from BLOCK
...
except ReleaseResourceError: # raised from __exit__
But I'm hoping there is a way to detect if it's a timeout error from within the with block.
I'm writing something that checks if a port is open, but modifying it to my use.
I set timeout for the check and if timeout reaches it raises socket.timeout exception, but I want a code block inside the try to also be invoked on socket.timeout:
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(5)
result = sock.connect_ex((check_server_ip, check_port))
if result == 0:
# act on open port
else:
# act on closed port
sock.close()
except socket.timeout:
# act on closed port
The code block I have on # act on closed port is long. I can create a function that has the code and call it on the else statement and socket.timeout exception, but I bet python has something more clever.
What can achieve this?
I don't think you need something clever or magical here. I looked at your code, then entered python -c "import this" in my terminal and saw this among the lines:
Flat is better than nested.
So, you don't need to create, set timeout and close a socket in the try ... except timeout - nothing throws timeout there:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(5)
try:
result = sock.connect_ex((check_server_ip, check_port))
socket_connected = result == 0
except socket.timeout:
socket_connected = False
if socket_connected:
do_connected_stuff()
else:
do_disconnected_stuff()
sock.close()
However, the correctness of this code really depends on if do_connected_stuff() can throw socket.timeout and if do_disconnected_stuff() is a meaningful action in this case. If yes to all questions, then you've already got a pretty much optimal structure - at least without the full view of your system.
I'm working on a basic socket client program in python and I'm not totally sure how to handle exceptions. This is what I did up to now:
TCP_IP = '..............'
TCP_PORT = 4950
MESSAGE = "o3"
BUFFER_SIZE = 2048
data = ""
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(5.0)
try:
s.connect((TCP_IP, TCP_PORT))
except socket.error:
#write error code to file
s.close()
try:
s.sendall(MESSAGE)
except socket.error:
#write to file or whatever
s.close()
try:
data = s.recv(BUFFER_SIZE)
except socket.error:
#write to file or whatever
s.close()
finally:
s.close()
The code is working as I want, but I'm not sure if I should nest try/catch blocks or not? Should I put socket.socket into try/catch block too?
Second question, what will s.settimeout() do in my case? As far as I understood the documentation, it will throw an exception after 5 seconds, but for what? Just connect or will it do the same for sendall and recv?
Since you're doing exactly the same actions in all the exception blocks and catching the same socket.error exception, you could put s.connect, s.sendall and s.recv in the same try: block. Like so:
try:
s.connect((TCP_IP, TCP_PORT))
s.sendall(MESSAGE)
data = s.recv(BUFFER_SIZE)
except socket.error:
#write error code to file
finally:
s.close()
Note that since s.close is also in the finally section in your example, it will always get called, even after an exception has occurred. So you'd end up with another exception occurring when you try to close an already closed socket. By not putting it in the except block and only in finally, you can avoid that situation.
If you do intend to handle each error in a different way, then you can leave them separate as you already have. But make sure to break/return at the end of the exception block so that you don't try the next. It's done that way in the socket examples, by using a continue in the loop.
Nesting them would help if you wanted to do something different in the exception block. But if not you'd be repeating the except block every time. And if you wanted to do something different, when you exit the nested-trys, you wouldn't be certain of which level it has completed or raised an exception - would need to use flag values etc. to merely track that. So for your example of the same error handling code, at the very least, do something like this in your except block:
except socket.error as e:
socket_error_handler(e, s)
def socket_error_handler(exception, socket):
#write error code to file
etc.
Should I put socket.socket into try/catch block too?
They do that in the examples, linked above.
Apart from logging, you shouldn't really be doing the same exception handling at each stage. Probably need to handle those separately.
Part 2:
s.settimeout(5.0) sets the timeout for each socket operation, not just the first connect. Also implies that it's in blocking mode.
I want to create socket errors (By doing things, obviously) but I've no idea how I should test if my script handles errors properly (If it dectes them.)
Currently, my code is this:
except socket.error as err:
print "Connection lost, waiting..."
time.sleep(5)
In theory, it should handle all the socket errors, print and then sleep (It's a part of a while loop.).
Any idea of how can I test it to see how it handles errors?
Use the raise statement:
try:
raise socket.error
except socket.error as err:
print "Connection lost, waiting..."
time.sleep(5)
Yet another example:
try:
raise AttributeError
except AttributeError:
print 'Sorry'
#Sorry
Also take a look at here and here
I am trying to have a client connect to my server, and have a stream of communication between them. The only reason the connection should break is due to network errors, or unless the client wants to stop talking.
The issue I am running into is keeping the handler in a tight loop, and parsing the JSON.
My server code is :
#!/usr/bin/env python
import SocketServer
import socket
import json
import time
class MyTCPServer(SocketServer.ThreadingTCPServer):
allow_reuse_address = True
class MyTCPServerHandler(SocketServer.BaseRequestHandler):
def handle(self):
while 1:
try:
networkData = (self.request.recv(1024).strip())
try:
jsonInputData = json.loads(networkData)
print jsonInputData
try:
if jsonInputData['type'] == 'SAY_HI':
print "HI"
except Exception, e:
print "no hi"
pass
try:
if jsonInputData['type'] == 'GO_AWAY':
print "Going away!"
except Exception, e:
print "no go away"
pass
except Exception, e:
pass
#time.sleep(0.001)
#print "JSON Error", e
except Exception, e:
#time.sleep(0.001)
pass
#print "No message", e
server = MyTCPServer(('192.168.1.115', 13373), MyTCPServerHandler)
server.serve_forever()
My client code is simple :
#!/usr/bin/env python
import socket
import json
import time
import sys
hostname = '192.168.1.103'
port = 13373
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((hostname,port))
except Exception, e:
print "Error, could not open socket: ", e
data = {'type':'SAY_HI'}
sock.send(json.dumps(data))
data = {'type':'SAY_BYE'}
sock.send(json.dumps(data))
Sometimes I'll see the messages being sent, "SAY_HI" and "SAY_BYE", but most of the times, no data is being displayed on the server side.
This question is really not clear, but calling self.request.recv(1024) is very likely not what you want to do. You're eliminating all of the nice application-level handling that TCP will happily do for you. If you change that to self.request.recv(8) or a similarly very small number (such that recv() returns whenever it receives data, and doesn't try to fill your buffer), you may get better results.
Ultimately this is super-simplistic change, even if it works, that will not work in a larger context. You will need to be handling exceptions from your json parser on the server side and waiting for more data until an entire well-formed message is received.
This is a hopelessly more complex subject than will be handled generally in any SO answer. If you're going to be doing any amount of raw sockets programming, you absolutely must own a copy of Unix Network Programming, Volume 1.