I am trying out pyro4 connection between my PC and Raspberry Pi 4.
Code on my PC is:
# saved as server.py
import Pyro4, Pyro4.naming
import socket, threading
# Define an object that will be accessible over the network.
# This is where all your code should go...
#Pyro4.expose
class MessageServer(object):
def show_message(self, msg):
print("Message received: {}".format(msg))
# Start a Pyro nameserver and daemon (server process) that are accessible
# over the network. This has security risks; see
# https://pyro4.readthedocs.io/en/stable/security.html
hostname = socket.gethostname()
ns_thread = threading.Thread(
target=Pyro4.naming.startNSloop, kwargs={'host': hostname}
)
ns_thread.daemon = True # automatically exit when main program finishes
ns_thread.start()
main_daemon = Pyro4.Daemon(host=hostname)
# find the name server
ns = Pyro4.locateNS()
# register the message server as a Pyro object
main_daemon_uri = main_daemon.register(MessageServer)
# register a name for the object in the name server
ns.register("example.message", main_daemon_uri)
# start the event loop of the main_daemon to wait for calls
print("Message server ready.")
main_daemon.requestLoop()
And code on my Raspberry is:
import Pyro4
import sys
print("Message:")
msg=sys.stdin.readline().strip()
message_server = Pyro4.Proxy("PYRONAME:192.168.1.5")
message_server.show_message(msg)
Code on my PC doesn t show any errors, but when I try to send a message from raspberry i get this:
What s your message?
test
Traceback (most recent call last):
File "/home/pi/.local/lib/python3.7/site-packages/Pyro4/socketutil.py", line 102, in getIpAddress
return getaddr(config.PREFER_IP_VERSION) if ipVersion is None else getaddr(ipVersion)
File "/home/pi/.local/lib/python3.7/site-packages/Pyro4/socketutil.py", line 94, in getaddr
ip = socket.getaddrinfo(hostname or socket.gethostname(), 80, family, socket.SOCK_STREAM, socket.SOL_TCP)[0][4][0]
File "/usr/lib/python3.7/socket.py", line 748, in getaddrinfo
for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
socket.gaierror: [Errno -2] Name or service not known
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/pi/.local/lib/python3.7/site-packages/Pyro4/core.py", line 515, in connect_and_handshake
sslContext=sslContext)
File "/home/pi/.local/lib/python3.7/site-packages/Pyro4/socketutil.py", line 266, in createSocket
if getIpVersion(connect[0]) == 4:
File "/home/pi/.local/lib/python3.7/site-packages/Pyro4/socketutil.py", line 68, in getIpVersion
address = getIpAddress(hostnameOrAddress)
File "/home/pi/.local/lib/python3.7/site-packages/Pyro4/socketutil.py", line 106, in getIpAddress
return getaddr(0)
File "/home/pi/.local/lib/python3.7/site-packages/Pyro4/socketutil.py", line 94, in getaddr
ip = socket.getaddrinfo(hostname or socket.gethostname(), 80, family, socket.SOCK_STREAM, socket.SOL_TCP)[0][4][0]
File "/usr/lib/python3.7/socket.py", line 748, in getaddrinfo
for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
socket.gaierror: [Errno -2] Name or service not known
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/home/pi/Desktop/client.py", line 10, in <module>
message_server.show_message(msg)
File "/home/pi/.local/lib/python3.7/site-packages/Pyro4/core.py", line 275, in __getattr__
self._pyroGetMetadata()
File "/home/pi/.local/lib/python3.7/site-packages/Pyro4/core.py", line 615, in _pyroGetMetadata
self.__pyroCreateConnection()
File "/home/pi/.local/lib/python3.7/site-packages/Pyro4/core.py", line 588, in __pyroCreateConnection
uri = _resolve(self._pyroUri, self._pyroHmacKey)
File "/home/pi/.local/lib/python3.7/site-packages/Pyro4/core.py", line 1915, in _resolve
return nameserver.lookup(uri.object)
File "/home/pi/.local/lib/python3.7/site-packages/Pyro4/core.py", line 275, in __getattr__
self._pyroGetMetadata()
File "/home/pi/.local/lib/python3.7/site-packages/Pyro4/core.py", line 615, in _pyroGetMetadata
self.__pyroCreateConnection()
File "/home/pi/.local/lib/python3.7/site-packages/Pyro4/core.py", line 596, in __pyroCreateConnection
connect_and_handshake(conn)
File "/home/pi/.local/lib/python3.7/site-packages/Pyro4/core.py", line 549, in connect_and_handshake
raise ce
Pyro4.errors.CommunicationError: cannot connect to ('JAKOB-PC', 9090): [Errno -2] Name or service not known
My PC has its firewall disabled, so there shouldn t be any problem with that. My local ip is 192.168.1.5.
I am using a headless Raspberry and write code on it with puTTY and VNC.
I have googled this error but couldn t find any answers. Any help would be appreciated.
I did this
#
# Server.py
#
from __future__ import print_function
import Pyro4
#Pyro4.expose
#Pyro4.behavior(instance_mode="single")
class Messenger(object):
# This is a constructor
def __init__(self):
pass
# This method will be called on the server
def send_message(self, name, message):
print("[{0}] {1}".format(name, message))
def main():
Pyro4.Daemon.serveSimple(
{
Messenger: "example.messenger"
},
ns=True)
if __name__ == "__main__":
main()
#
# Client.py
#
# This is the code that visits the warehouse.
import sys
import Pyro4
import Pyro4.util
sys.excepthook = Pyro4.util.excepthook
messenger = Pyro4.Proxy("PYRONAME:example.messenger#192.168.1.5")
messenger.send_message("Tim", "Hello!")
Then ran
python -m Pyro4.naming -n 192.168.1.5
python Server.py
python Client.py
In short I couldn't solve the problem with Pyro and (almost) no one helped so I decided to use 'websockets' instead.
You can read the documentation here but I'll explain it here anyway.
First of all you need two devices with network connection. You also have to run python 3.6.1 on both of them. After that you also need to install websockets if you don't have them already with pip install websockets or as I had to do it with pip3 install websockets.
Code below runs on the server and handles messages you send to it from client. Function 'hello' is a simple example of processing request and sending back a response. 'request' is the data server receives, that data must be bytes, string on iterable. Response is made by converting request to integer, squaring it and converting it back to string. This response is then sent back to client.
'start_server' defines the server, function that will define its behavior(hello), ip address on witch the server is running on(192.168.1.117) and port on witch it will receive requests(8765).
!/usr/bin/env python
import asyncio
import websockets
print("Running...")
async def hello(websocket, path):
request = await websocket.recv()
print("Request: " + request)
response = str(int(request)*int(request))
await websocket.send(response)
print("Response:" + response)
start_server = websockets.serve(hello, "192.168.1.117", 8765)
asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()
Next bit is code on the client. 'uri' is ip and port of the server. Function 'tellServ' asks you to input some data('tell' variable) and sends it to the server. After that it waits for reply and once it gets it it prints it out. In this case if I would input number "6" server would reply with "36". Function loop is in a while loop so I can send multiple numbers without having to restart the script.
#!/usr/bin/env python
import asyncio
import websockets
uri = "ws://192.168.1.117:8765"
async def tellServ():
async with websockets.connect(uri) as websocket:
tell = input("Podatek ki ga posles: ")
await websocket.send(tell)
reply = await websocket.recv()
print("Odgovor:")
print(reply)
while 1:
asyncio.get_event_loop().run_until_complete(tellServ())
Related
Error stack seen on running the sender and receiver files
Traceback (most recent call last):
File "C:/Users/A3245643/PycharmProjects/events/receive.py", line 7, in <module>
connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))
File "C:\Users\A6002043\AppData\Local\Programs\Python\Python38\lib\site-packages\pika\adapters\blocking_connection.py", line 359, in __init__
self._impl = self._create_connection(parameters, _impl_class)
File "C:\Users\A6002043\AppData\Local\Programs\Python\Python38\lib\site-packages\pika\adapters\blocking_connection.py", line 450, in _create_connection
raise self._reap_last_connection_workflow_error(error)
pika.exceptions.AMQPConnectionError
send.py file acts as producer
#!/usr/bin/env python
import pika
connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()
channel.queue_declare(queue='iptbotQueue')
channel.basic_publish(exchange='test-exchange',
routing_key='iptbotQueue',
body='Hello World!')
print(" [x] Sent 'Hello World!'")
connection.close()
recieve.py acts as consumer
# from send import channel
import pika, sys, os
connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))
channel = connection.channel()
channel.queue_declare(queue='iptbotQueue')
def callback(ch, method, properties, body):
print(" [x] Received %r" % body)
channel.basic_consume(queue='iptbotQueue',
auto_ack=True,
on_message_callback=callback)
print(' [*] Waiting for messages. To exit press CTRL+C')
channel.start_consuming()
I have already set the rabbit mq , so should I replace the localhost value with the url seen below in image?
I figured out I need to provide the IP address ( example : 172.11.12.33) for localhost value
or just host name without adding "http" example slacktestbot-mq.omnitank.bestbuy.com
I'm learning thenextquant quant framework, but always get connection error while connecting to RabbitMQ. after some troubleshooting, i found asynico/aioamqp module always prompts error:An open stream was garbage collected prior to establishing network connection; call "stream.close()" explicitly.
while trying to connect to RabbitMQ server, RabbitMQ is up and running and other client can connect to it without any error.
Then I followed the hello world example from aioamqp(https://github.com/Polyconseil/aioamqp/blob/master/examples/send.py) to write a test program, then reproduced the error.
import asyncio
import aioamqp
async def send():
transport, protocol = await aioamqp.connect(host="127.0.0.1", port=5672, login="guest", password="guest", login_method="PLAIN")
channel = await protocol.channel()
await channel.queue_declare(queue_name='hello')
await channel.basic_publish(
payload='Hello World!',
exchange_name='',
routing_key='hello'
)
print(" [x] Sent 'Hello World!'")
await protocol.close()
transport.close()
asyncio.get_event_loop().run_until_complete(send())
(venv_380) appledeMBP:Market apple$ python hello.py
An open stream was garbage collected prior to establishing network connection; call "stream.close()" explicitly.
Traceback (most recent call last):
File "hello.py", line 31, in <module>
asyncio.get_event_loop().run_until_complete(send())
File "/Users/apple/.pyenv/versions/3.8.0/lib/python3.8/asyncio/base_events.py", line 608, in run_until_complete
return future.result()
File "hello.py", line 14, in send
transport, protocol = await aioamqp.connect(host="127.0.0.1", port=5672, login="guest", password="guest", login_method="PLAIN")
File "/Users/apple/.virtualenvs/venv_380/lib/python3.8/site-packages/aioamqp/__init__.py", line 59, in connect
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
File "/Users/apple/.pyenv/versions/3.8.0/lib/python3.8/asyncio/trsock.py", line 82, in setsockopt
self._sock.setsockopt(*args, **kwargs)
OSError: [Errno 9] Bad file descriptor
finally I found it's caused by version of Python. the issue is gone once using 3.6 instead of 3.8 which result in connection issue with aioamqp.connect()
At the moment i am writing a syslog client that will send messages to a remote syslog server. So far this is working pretty ok but i am running into the following problem.
When the syslog server goes down for some reason i need to catch this so the program will stop sending syslog messages and we can investigate the problem.
Unfortunately, the program continues running and doesn't see that the TCP socket is closed and raise an exception.
I only receive a traceback in my terminal:
--- Logging error --- Traceback (most recent call last):
File "C:\Users\Administrator\AppData\Local\Programs\Python\Python37\lib\logging\handlers.py", line 941, in emit
self.socket.sendall(msg) ConnectionAbortedError: [WinError 10053] Call stack:
File "c:\Users\Administrator\.vscode\extensions\ms-python.python-2018.12.1\pythonFiles\ptvsd_launcher.py", line 45, in <module>
main(ptvsdArgs)
File "c:\Users\Administrator\.vscode\extensions\ms-python.python-2018.12.1\pythonFiles\lib\python\ptvsd\__main__.py", line 265, in main
wait=args.wait)
File "c:\Users\Administrator\.vscode\extensions\ms-python.python-2018.12.1\pythonFiles\lib\python\ptvsd\__main__.py", line 258, in handle_args
debug_main(addr, name, kind, *extra, **kwargs)
File "c:\Users\Administrator\.vscode\extensions\ms-python.python-2018.12.1\pythonFiles\lib\python\ptvsd\_local.py", line 45, in debug_main
run_file(address, name, *extra, **kwargs)
File "c:\Users\Administrator\.vscode\extensions\ms-python.python-2018.12.1\pythonFiles\lib\python\ptvsd\_local.py", line 79, in run_file
run(argv, addr, **kwargs)
File "c:\Users\Administrator\.vscode\extensions\ms-python.python-2018.12.1\pythonFiles\lib\python\ptvsd\_local.py", line 140, in _run
_pydevd.main()
File "c:\Users\Administrator\.vscode\extensions\ms-python.python-2018.12.1\pythonFiles\lib\python\ptvsd\_vendored\pydevd\pydevd.py", line 1925, in main
debugger.connect(host, port)
File "c:\Users\Administrator\.vscode\extensions\ms-python.python-2018.12.1\pythonFiles\lib\python\ptvsd\_vendored\pydevd\pydevd.py", line 1283, in run
return self._exec(is_module, entry_point_fn, module_name, file, globals, locals)
File "c:\Users\Administrator\.vscode\extensions\ms-python.python-2018.12.1\pythonFiles\lib\python\ptvsd\_vendored\pydevd\pydevd.py", line 1290, in _exec
pydev_imports.execfile(file, globals, locals) # execute the script
File "c:\Users\Administrator\.vscode\extensions\ms-python.python-2018.12.1\pythonFiles\lib\python\ptvsd\_vendored\pydevd\_pydev_imps\_pydev_execfile.py", line 25, in execfile
exec(compile(contents+"\n", file, 'exec'), glob, loc)
File "c:\Users\Administrator\OneDrive\Documents\Python Scripts\testlogger.py", line 71, in <module>
my_logger.info(i) Message: 'test4' Arguments: ()
Relevant code:
my_logger = logging.getLogger('MyLogger')
my_logger.setLevel(logging.ERROR)
my_logger.setLevel(logging.INFO)
my_logger.setLevel(logging.DEBUG)
try:
handler = logging.handlers.SysLogHandler(('IP ADDRESS HOST', 514), socktype=socket.SOCK_STREAM)
my_logger.addHandler(handler)
except Exception as e:
print (e)
list1 = ['test','test2','test3','test4','test5','test6','test7','test8']
for i in list1:
try:
my_logger.info(i) #here i expected that an exception would be raised when the TCP socket is not alive anymore
except Exception as e:
print (e)
How can i make sure that the program stops and i can do the appropriate exception handling?
Thanks!
The default behavior of the SysLogHandler class (and all the ones who are using TCP) is to retry a connection, this is explained in the docs of the createSocket() method:
Tries to create a socket; on failure, uses an exponential back-off
algorithm. On initial failure, the handler will drop the message it
was trying to send. When subsequent messages are handled by the same
instance, it will not try connecting until some time has passed. The
default parameters are such that the initial delay is one second, and
if after that delay the connection still can’t be made, the handler
will double the delay each time up to a maximum of 30 seconds.
This behaviour is controlled by the following handler attributes:
retryStart (initial delay, defaulting to 1.0 seconds).
retryFactor (multiplier, defaulting to 2.0).
retryMax (maximum delay, defaulting to 30.0 seconds).
As it doesn't seem to have an option for the behavior of "not retrying" which you seem to want, so if you really want that you can create your own handler by subclassing it and overriding the createSocket() method with something like:
class MySysLogHandler(logging.handlers.SysLogHandler):
def createSocket(self):
try:
self.sock = self.makeSocket()
except OSError:
# do your own error handling here ...
You can dig a bit more by looking at the source code of createSocket() in CPython Github repo (beware, this is from master branch and might not be the exact version of Python you're using)
I switched to another solution and stopped using the SyslogHandler class.
I now use the following class were i wrote my own syslog sender through a socket.
class Syslog:
def __init__(self,host="localhost",port=514,facility=Facility.DAEMON):
self.host = host
self.port = port
self.facility = facility
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
def connect(self):
try:
self.socket.connect((self.host, self.port))
except Exception as e:
print("failed setting up connection")
def send(self, message,level):
data = "<%d>%s" % (level + self.facility*8, message + "\n")
try:
self.socket.sendall(data.encode('utf-8'))
except Exception as e:
print("send failed")
#if __name__ == '__main__':
syslog1 = Syslog(host='HOSTIPADDRESS-NAME')
syslog1.connect()
messages = ["test1","test2","test3","test4","test5","test6","test7"]
for message in messages:
syslog1.send(message,Level.WARNING)
This is working quite well and runs into an exception when the syslog server goes down unexpectedly. The only problem now i discovered while debugging is the following:
When i shut down the syslog server it throws not immediatly an exception when i try to send a message.
Please see example below:
1.) the syslog server is started, i send the first message "test1" from the for loop, successfull.
2.) i shutdown the syslog server, now i send the second message "test2" from the for loop. Nothing happens, no exception!
3.) i send the third message "test3", now an exception is thrown.
How is this possible?
I have already been through these set of solutions for connecting IMAP under proxy
Information to add:
I am trying to write a python code that can fetch mails from gmails IMAP server using imapclient under http,https and socks proxy server of my academic insitute
When tried without any proxy handling, it used to give error
socket.error [101] network is unreachable
import imapclient
import pyzmail
imapObj = imapclient.IMAPClient('imap.gmail.com',ssl=True)
imapObj.login('***********#gmail.com','*********')
imapObj.select_folder('INBOX', readonly=True)
UIDs = imapObj.search(['SINCE 07-Jul-2016'])
for item in UIDs:
rawMessages = imapObj.fetch(item, ['BODY[]', 'FLAGS'])
message = pyzmail.PyzMessage.factory(rawMessages[item]['BODY[]'])
message.get_subject()
message.get_addresses('from')
message.get_addresses('to')
message.get_addresses('cc')
message.get_addresses('bcc')
message.text_part != None
message.text_part.get_payload().decode(message.text_part.charset)
message.html_part != None
message.html_part.get_payload().decode(message.html_part.charset)
imapObj.logout()
However, the process gives error as
File "mailtotext.py", line 16, in <module>
imapObj = imapclient.IMAPClient('imap.gmail.com',ssl=True)
File "/usr/local/lib/python2.7/dist-packages/imapclient/imapclient.py", line 152, in __init__
self._imap = self._create_IMAP4()
File "/usr/local/lib/python2.7/dist-packages/imapclient/imapclient.py",line 164, in _create_IMAP4
self._timeout)
File "/usr/local/lib/python2.7/dist-packages/imapclient/tls.py", line 153, in __init__
imaplib.IMAP4.__init__(self, host, port)
File "/usr/lib/python2.7/imaplib.py", line 172, in __init__
self.open(host, port)
File "/usr/local/lib/python2.7/dist-packages/imapclient/tls.py", line 158, in open
sock = socket.create_connection((host, port), self._timeout)
File "/usr/lib/python2.7/socket.py", line 571, in create_connection
raise err
socket.error: [Errno 101] Network is unreachable
I then followed the above mentioned link procedures owing to my institute proxy as http,https,socks
I have already set my system proxy settings as
http_proxy="http://10.3.100.207:8080/"
https_proxy="https://10.3.100.207:8080/"
ftp_proxy="ftp://10.3.100.207:8080/"
socks_proxy="socks://10.3.100.207:8080/"
and edited the code as
import imapclient
import pyzmail
import socks
import socket
socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS4,"10.3.100.207",8080,True)
socket.socket = socks.socksocket
imapObj = imapclient.IMAPClient('imap.gmail.com',ssl=True)
imapObj.login('***********#gmail.com','*********')
imapObj.select_folder('INBOX', readonly=True)
UIDs = imapObj.search(['SINCE 07-Jul-2016'])
for item in UIDs:
rawMessages = imapObj.fetch(item, ['BODY[]', 'FLAGS'])
message = pyzmail.PyzMessage.factory(rawMessages[item]['BODY[]'])
message.get_subject()
message.get_addresses('from')
message.get_addresses('to')
message.get_addresses('cc')
message.get_addresses('bcc')
message.text_part != None
message.text_part.get_payload().decode(message.text_part.charset)
message.html_part != None
message.html_part.get_payload().decode(message.html_part.charset)
imapObj.logout()
But this process seems to freeze for very long time and finally I always need to make a keyboard interrupt. Its sure that it was freezed somewhere in socket files as per keyboard interrupt output.
Please help me through this, there are hardly solution to such problems over web. I have even tried tunneling but it isn't solving my problem or say making it worse (I might have not implemented it well :P)I would provide any other information and output if needed here
While trying to set up a Websocket server, I have encountered the following error.
The same code works fine under LAN IP '192.168.x.x', but fails to work with a public ip/domain name
Here is the error trace
Traceback (most recent call last):
File "WSServer.py", line 19, in <module>
server = loop.run_until_complete(coro)
File "/usr/lib64/python3.4/asyncio/base_events.py", line 208, in run_until_complete
return future.result()
File "/usr/lib64/python3.4/asyncio/futures.py", line 243, in result
raise self._exception
File "/usr/lib64/python3.4/asyncio/tasks.py", line 319, in _step
result = coro.send(value)
File "/usr/lib64/python3.4/asyncio/base_events.py", line 579, in create_server
% (sa, err.strerror.lower()))
OSError: [Errno 99] error while attempting to bind on address ('121.6.x.x', 9000): cannot assign requested address
Python Server Code:
from autobahn.asyncio.websocket import WebSocketServerProtocol
class MyServerProtocol(WebSocketServerProtocol):
def onMessage(self, payload, isBinary):
print("message received")
self.sendMessage(payload, isBinary)
if __name__ == '__main__':
import asyncio
from autobahn.asyncio.websocket import WebSocketServerFactory
factory = WebSocketServerFactory()
factory.protocol = MyServerProtocol
loop = asyncio.get_event_loop()
coro = loop.create_server(factory, '121.6.x.x', 9000)
server = loop.run_until_complete(coro)
try:
loop.run_forever()
except KeyboardInterrupt:
pass
finally:
server.close()
loop.close()
Could the issue be related with the server setting? e.g. hostname, SELinux