Is there any code snippet sample to achieve the following requirement,
python-asyncio TCP Server listen for TCP client and manage open connection simultaneously to another remote TCP server.
the tcp server code that I've tried so far, based on: http://asyncio.readthedocs.io/en/latest/tcp_echo.html1
HOST, PORT = '127.0.0.1', 8888
VHOST, VPORT = "localhost", 9999
vsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
vsock.connect((VHOST, VPORT))
async def send_message(message, vsock):
receive = None
try:
vsock.sendall(message)
received = vsock.recv(1024)
except:
print("Unexpected error:", sys.exc_info()[0])
raise
return received
async def handle_echo(reader, writer):
task = loop.create_task(send_message(data, vsock))
response = await task
writer.write(response)
await writer.drain()
writer.close()
loop = asyncio.get_event_loop()
coro = asyncio.start_server(handle_echo, HOST, PORT, loop=loop)
server = loop.run_until_complete(coro)
try:
loop.run_forever()
except KeyboardInterrupt:
pass
server.close()
loop.run_until_complete(server.wait_closed())
loop.close()
vsock.close()
It works on first request, but getting blank message in 2nd request, and getting error the next request
Unexpected error: <class 'BrokenPipeError'>
Task exception was never retrieved
future: <Task finished coro=<handle_echo() done, defined at socket_server.py:27> exception=BrokenPipeError(32, 'Broken pipe')>
Traceback (most recent call last):
File "/home/hery/.pyenv/versions/3.5.1/lib/python3.5/asyncio/tasks.py", line 241, in _step
result = coro.throw(exc)
File "socket_server.py", line 34, in handle_echo
response = await task
File "/home/hery/.pyenv/versions/3.5.1/lib/python3.5/asyncio/futures.py", line 358, in __iter__
yield self # This tells Task to wait for completion.
File "/home/hery/.pyenv/versions/3.5.1/lib/python3.5/asyncio/tasks.py", line 290, in _wakeup
future.result()
File "/home/hery/.pyenv/versions/3.5.1/lib/python3.5/asyncio/futures.py", line 274, in result
raise self._exception
File "/home/hery/.pyenv/versions/3.5.1/lib/python3.5/asyncio/tasks.py", line 239, in _step
result = coro.send(None)
File "socket_server.py", line 18, in send_message
vsock.sendall(message)
BrokenPipeError: [Errno 32] Broken pipe
Related
I'm trying to connect to a ble device with bleak that uses a passkey.
async def connect(self, address):
print("Connecting to device...")
async with BleakClient(address) as client:
response = await client.connect()
print(response)
i'm using above code. The device displays the passkey to enter and windows displays the add a device message to input the code, but i get a timeout error from asyncio and never recieve the response to python.
Traceback (most recent call last):
File "C:\Users\halmelam\PycharmProjects\read_passcode\main.py", line 137, in <module>
asyncio.run(pair.connect(device.address))
File "C:\Users\halmelam\AppData\Local\Programs\Python\Python39\lib\asyncio\runners.py", line 44, in run
return loop.run_until_complete(main)
File "C:\Users\halmelam\AppData\Local\Programs\Python\Python39\lib\asyncio\base_events.py", line 642, in run_until_complete
return future.result()
File "C:\Users\halmelam\PycharmProjects\read_passcode\main.py", line 95, in connect
response = await client.connect()
File "C:\Users\halmelam\.virtualenvs\read_passcode\lib\site-packages\bleak\backends\winrt\client.py", line 249, in connect
await asyncio.wait_for(event.wait(), timeout=timeout)
File "C:\Users\halmelam\AppData\Local\Programs\Python\Python39\lib\asyncio\tasks.py", line 494, in wait_for
raise exceptions.TimeoutError() from exc
asyncio.exceptions.TimeoutError
How do I get the response and how can i send the passkey via python?
I want to try Multi Agent programming in Python using SPADE, but i can't seem to make this simple example work. The error refers to the server, so how can i set up the agents to work in the localhost ?
here is my code :
class SenderAgent(Agent):
class InformBehav(OneShotBehaviour):
async def run(self):
print("InformBehav running")
msg = Message(to="receiveragent#127.0.0.1") # Instantiate the message
msg.set_metadata("performative", "inform") # Set the "inform" FIPA performative
msg.body = "Hello World" # Set the message content
await self.send(msg)
print("Message sent!")
# stop agent from behaviour
await self.agent.stop()
async def setup(self):
print("SenderAgent started")
b = self.InformBehav()
self.add_behaviour(b)
class ReceiverAgent(Agent):
class RecvBehav(OneShotBehaviour):
async def run(self):
print("RecvBehav running")
msg = await self.receive(timeout=10) # wait for a message for 10 seconds
if msg:
print("Message received with content: {}".format(msg.body))
else:
print("Did not received any message after 10 seconds")
# stop agent from behaviour
await self.agent.stop()
async def setup(self):
print("ReceiverAgent started")
b = self.RecvBehav()
template = Template()
template.set_metadata("performative", "inform")
self.add_behaviour(b, template)
if __name__ == "__main__":
receiveragent = ReceiverAgent("receiveragent#127.0.0.1", '1234')
future = receiveragent.start()
future.result() # wait for receiver agent to be prepared.
senderagent = SenderAgent("senderagent#127.0.0.1", '1234')
senderagent.start()
while receiveragent.is_alive():
try:
time.sleep(1)
except KeyboardInterrupt:
senderagent.stop()
receiveragent.stop()
break
print("Agents finished")
as i'm getting the following errors :
connection failed: [Errno 10061] Connect call failed ('127.0.0.1', 5222)
Traceback (most recent call last):
File "C:/Users/Administrateur/PycharmProjects/spade/test.py", line 53, in <module>
future.result() # wait for receiver agent to be prepared.
File "C:\Users\Administrateur\AppData\Local\Programs\Python\Python37\lib\concurrent\futures\_base.py", line 435, in result
return self.__get_result()
File "C:\Users\Administrateur\AppData\Local\Programs\Python\Python37\lib\concurrent\futures\_base.py", line 384, in __get_result
raise self._exception
File "C:\Users\Administrateur\AppData\Local\Programs\Python\Python37\lib\site-packages\spade\agent.py", line 100, in _async_start
await self._async_register()
File "C:\Users\Administrateur\AppData\Local\Programs\Python\Python37\lib\site-packages\spade\agent.py", line 142, in _async_register
_, stream, features = await aioxmpp.node.connect_xmlstream(self.jid, metadata, loop=self.loop)
File "C:\Users\Administrateur\AppData\Local\Programs\Python\Python37\lib\site-packages\aioxmpp\node.py", line 415, in connect_xmlstream
exceptions
aioxmpp.errors.MultiOSError: failed to connect to XMPP domain '127.0.0.1': multiple errors: [Errno 10061] Connect call failed ('127.0.0.1', 5222)
I am asking where either my though process or my code is incorrect relative to using asyncio client streams to send data and receive responses from a server. When I call the method that disconnects the client an exception is thrown. I am learning python asyncio and ran across exceptions during testing trying to close the client connection. I am trying to 1). Create a client connection to a server 2). leave the client connection open so that it can be used across multiple send/receive cycles 3). close the client connection gracefully when complete.
This is the class that contains the asyncio methods to create the stream writer.
class hl7_client_sender:
SB = b'\x1B'
EB = b'\x1C'
CR = b'\x0D'
def __init__(self,address,port,timeout=-1,retry=3.0):
self._resend=0
self._timeout= timeout
self._retry = retry
#self._reader, self._writer = await asyncio.open_connection(address,port)
self._address = address
self._port = port
self._writer = None
self._reader = None
async def connect(self):
self._reader, self._writer = await asyncio.open_connection(self._address,self._port)
async def disconnect(self):
await self._writer.wait_closed()
and this is the code in my driver where the exception occurs during the call to disconnect
#test send and respond
import asyncio
import string
import unicodedata
import simple_hl7_client
import time
##open a connectino sleep 5 seconds then close###
myclient = simple_hl7_client.hl7_client_sender('192.168.226.128',54321)
asyncio.run(myclient.connect())
time.sleep(3)
asyncio.run(myclient.disconnect())
The exception occurs during the call to asycnio.run(myclient.disconnect())
This is the exception:
Traceback (most recent call last):
File ".\test_simple_hl7_client.py", line 11, in <module>
asyncio.run(myclient.disconnect())
File "C:\Users\billg\AppData\Local\Programs\Python\Python37\lib\asyncio\runners.py", line 43, in run
return loop.run_until_complete(main)
File "C:\Users\billg\AppData\Local\Programs\Python\Python37\lib\asyncio\base_events.py", line 583, in run_until_complete
return future.result()
File "D:\data\FromOldPC\code\ASYNCIOTESTING\simple_hl7_client.py", line 23, in disconnect
self._writer.close()
File "C:\Users\billg\AppData\Local\Programs\Python\Python37\lib\asyncio\streams.py", line 317, in close
return self._transport.close()
File "C:\Users\billg\AppData\Local\Programs\Python\Python37\lib\asyncio\selector_events.py", line 663, in close
self._loop.call_soon(self._call_connection_lost, None)
File "C:\Users\billg\AppData\Local\Programs\Python\Python37\lib\asyncio\base_events.py", line 687, in call_soon
self._check_closed()
File "C:\Users\billg\AppData\Local\Programs\Python\Python37\lib\asyncio\base_events.py", line 479, in _check_closed
raise RuntimeError('Event loop is closed')
RuntimeError: Event loop is closed
Part of my script:
def testConnection(self):
# This code doesn't work
try:
self.imap.login(self.user, self.password)
return True
except:
return False
When I try to connect with imaplib to mail server with wrong settings, script always crashes with this error:
Traceback (most recent call last):
File "./mail-notifier.py", line 198, in <module>
mail_check()
File "./mail-notifier.py", line 161, in mail_check
if (SettingsExist() == True and Mail().testConnection() == True):
File "./mail-notifier.py", line 142, in __init__
self.imap = imaplib.IMAP4_SSL(settings.value("MailServer"), settings.value("Port"))
File "/usr/lib64/python3.4/imaplib.py", line 1221, in __init__
IMAP4.__init__(self, host, port)
File "/usr/lib64/python3.4/imaplib.py", line 181, in __init__
self.open(host, port)
File "/usr/lib64/python3.4/imaplib.py", line 1234, in open
IMAP4.open(self, host, port)
File "/usr/lib64/python3.4/imaplib.py", line 257, in open
self.sock = self._create_socket()
File "/usr/lib64/python3.4/imaplib.py", line 1224, in _create_socket
sock = IMAP4._create_socket(self)
File "/usr/lib64/python3.4/imaplib.py", line 247, in _create_socket
return socket.create_connection((self.host, self.port))
File "/usr/lib64/python3.4/socket.py", line 512, in create_connection
raise err
File "/usr/lib64/python3.4/socket.py", line 503, in create_connection
sock.connect(sa)
socket.timeout: timed out
I can't catch timeout exception and print error message and continue to work. I thought " except: " catches all errors that happen. I tried to set " except socket.timeout: " but unsuccessfully. What did I wrong?
socket.connect(address)
Connect to a remote socket at address. (The format of address depends on the address family — see above.)
If the connection is interrupted by a signal, the method waits until the connection completes, or raise a socket.timeout on timeout, if the signal handler doesn’t raise an exception and the socket is blocking or has a timeout. For non-blocking sockets, the method raises an InterruptedError exception if the connection is interrupted by a signal (or the exception raised by the signal handler).
Changed in version 3.5: The method now waits until the connection completes instead of raising an InterruptedError exception if the connection is interrupted by a signal, the signal handler doesn’t raise an exception and the socket is blocking or has a timeout (see the PEP 475 for the rationale).
In case of remote connection you should check if the Internet connection can be established (you and remote destination are reachable) and connection setting to perform actions you want are correct.
I am new to Python 3 and am playing around with asyncio. Thereby, I am experiencing a strange behavior with the following server-side code:
import asyncio
#asyncio.coroutine
def handle_client(reader, writer):
print('Client connected.')
client_connected = True
while client_connected:
print('Waiting for client event.')
line = yield from reader.readline()
if line:
print('Got: {}'.format(line))
if line.decode() == 'echo\n':
print('Sending back echo.')
writer.write(line)
else:
print('Not sending back anything.')
else:
print('Client disconnected.')
client_connected = False
if __name__ == '__main__':
asyncio.async(asyncio.start_server(handle_client, 'localhost', 8888))
asyncio.get_event_loop().run_forever()
When I run this client code (EDIT: client code is entered manually into an IPython session, the server definitely has time to write before I close the socket)...
import socket
client = socket.create_connection(('localhost', 8888))
client.sendall('echo\n'.encode())
client.close()
... I get an error traceback from the server:
C:\Users\Gnar\Anaconda3\python.exe C:/Users/Gnar/Code/echo.py
Client connected.
Waiting for client event.
Got: b'echo\n'
Sending back echo.
Waiting for client event.
Task exception was never retrieved
future: <Task finished coro=<handle_client() done, defined at C:/Users/Gnar/Code/echo.py:4> exception=ConnectionResetError(10054, 'An existing connection was forcibly closed by the remote host', None, 10054, None)>
Traceback (most recent call last):
File "C:\Users\Gnar\Anaconda3\lib\asyncio\tasks.py", line 234, in _step
result = coro.throw(exc)
File "C:/Users/Gnar/Code/echo.py", line 10, in handle_client
line = yield from reader.readline()
File "C:\Users\Gnar\Anaconda3\lib\asyncio\streams.py", line 425, in readline
yield from self._wait_for_data('readline')
File "C:\Users\Gnar\Anaconda3\lib\asyncio\streams.py", line 393, in _wait_for_data
yield from self._waiter
File "C:\Users\Gnar\Anaconda3\lib\asyncio\futures.py", line 386, in __iter__
yield self # This tells Task to wait for completion.
File "C:\Users\Gnar\Anaconda3\lib\asyncio\tasks.py", line 287, in _wakeup
value = future.result()
File "C:\Users\Gnar\Anaconda3\lib\asyncio\futures.py", line 275, in result
raise self._exception
File "C:\Users\Gnar\Anaconda3\lib\asyncio\selector_events.py", line 662, in _read_ready
data = self._sock.recv(self.max_size)
ConnectionResetError: [WinError 10054] An existing connection was forcibly closed by the remote host
The issue must be somehow in relation with writer.write, because when I call the following client code (which makes the server skip the writing), there is no error:
import socket
client = socket.create_connection(('localhost', 8888))
client.sendall('foo\n'.encode())
client.close()
The corresponding server log:
C:\Users\Gnar\Anaconda3\python.exe C:/Users/Gnar/Code/echo.py
Client connected.
Waiting for client event.
Got: b'foo\n'
Not sending back anything.
Waiting for client event.
Client disconnected.
What am I missing? Am I using asyncio incorrectly?
Thanks!
You're getting the exception because you're trying to write some data back to the client on the server-side, but the client is closing the socket immediately after sending in the 'echo', without actually receiving the response from the server. If a socket connection is closed while there is unreceived data on the wire, you'll get an error on the sending side, so that you know the remote side may not have received whatever you last sent.
The problem goes away if you add a call to socket.recv(1024) on the client-side prior to calling socket.close(), so that the client waits for a response from the server before closing the socket. You could also just use a try/except around the write call on the server-side if you just want to gracefully handle the exception, even when the client does the wrong thing.