Issue
You need to write code for the tcp server. The first client that connects will only send some data to the server, so the server should only read that data. The second client should only read the data, therefore the server should only send some data to this client. In my case, the server should send data to the second client every 3 seconds.
How can I use two tcp connections at the same time. One to receive data and the other to send it?
It is necessary to use asynchrony in the python language.
I tried, here is my code.
server.py
import asyncio
import time
import logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s,%(levelname)s:%(message)s',
datefmt='%d-%m-%Y %H:%M:%S'
)
client_loop = True
first_client_addr = None
msg = 'test'
async def handle_client(reader, writer):
global client_loop
global first_client_addr
global msg
addr = writer.get_extra_info('peername')
logging.info(f'New client {addr}')
if first_client_addr == None:
first_client_addr = addr
if addr == first_client_addr:
request = None
while client_loop:
request = (await reader.read(1024)).decode('utf8')
msg = request
logging.info(f'Received {request!r} from {addr!r}')
else:
while client_loop:
response = msg
writer.write(response.encode('utf8'))
await writer.drain()
logging.info(f'Sended {response!r} to {addr!r}')
time.sleep(3)
writer.close()
async def run_server():
server = await asyncio.start_server(handle_client, '0.0.0.0', 8686)
async with server:
await server.serve_forever()
asyncio.run(run_server())
The first step is to connect the client to send user data.
Then, as soon as the second client connects, I stop receiving any data from the first client, that is, they simply cannot be read.
As soon as I kill the second client, the server starts reading data from the first client again. Server log:
08-04-2022 17:19:23,INFO:New client ('127.0.0.1', 47314)
08-04-2022 17:19:23,INFO:Received 'First connection message, client 2.' from ('127.0.0.1', 47314)
08-04-2022 17:19:25,INFO:Received 'g' from ('127.0.0.1', 47314)
08-04-2022 17:19:26,INFO:Received 'a' from ('127.0.0.1', 47314)
08-04-2022 17:19:27,INFO:New client ('127.0.0.1', 47316)
08-04-2022 17:19:27,INFO:Sended 'a' to ('127.0.0.1', 47316)
08-04-2022 17:19:30,INFO:Sended 'a' to ('127.0.0.1', 47316)
08-04-2022 17:19:33,INFO:Sended 'a' to ('127.0.0.1', 47316)
08-04-2022 17:19:36,INFO:Sended 'a' to ('127.0.0.1', 47316)
08-04-2022 17:19:39,INFO:Sended 'a' to ('127.0.0.1', 47316)
08-04-2022 17:19:42,INFO:Sended 'a' to ('127.0.0.1', 47316)
08-04-2022 17:19:45,INFO:Sended 'a' to ('127.0.0.1', 47316)
08-04-2022 17:19:48,INFO:Sended 'a' to ('127.0.0.1', 47316)
How can this happen, because these are two different clients that should not influence each other. Please help me solve this problem. Explain why this is happening or write code.
Here is the code of two of my clients, but it is not really needed.
client_send.py
import asyncio
import time
async def send_client():
reader, writer = await asyncio.open_connection(
'127.0.0.1', 8686
)
message = 'First connection message, client 2.'
writer.write(message.encode())
await writer.drain()
print('First connection for client 2 done.')
print('Start loop')
data = None
while data != 'quit':
data = input()
writer.write(data.encode())
await writer.drain()
print('Close the connection')
writer.close()
await writer.wait_closed()
asyncio.run(send_client())
client_listen.py
import asyncio
async def listen_client():
reader, writer = await asyncio.open_connection(
'127.0.0.1', 8686
)
message = 'First connection message, client 1.'
writer.write(message.encode())
await writer.drain()
print('First connection for client 1 done.')
print('Loop has been started')
data = None
while data != 'quit':
response = await reader.read(1024)
data = response.decode()
print(f'Received: {data!r}')
print('Close the connection')
writer.close()
await writer.wait_closed()
asyncio.run(listen_client())
Solution
The problem is this sleep(3)
. This put to sleep the whole server so it isn't receiving/sending anything. In asyncio code you need to use await asyncio.sleep(3)
.
I also slightly restructured the server code:
import asyncio
import logging
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s,%(levelname)s:%(message)s",
datefmt="%d-%m-%Y %H:%M:%S",
)
msg = "test"
clients = []
async def handle_read(reader, addr):
global msg
while True:
msg = (await reader.read(1024)).decode("utf-8")
logging.info(f"Received {msg!r} from {addr!r}")
async def handle_write(writer, addr):
while True:
await asyncio.sleep(3)
writer.write(msg.encode("utf8"))
await writer.drain()
logging.info(f"Sended {msg!r} to {addr!r}")
async def handle_client(reader, writer):
global num_clients
addr = writer.get_extra_info("peername")
logging.info(f"New client {addr}")
if not clients:
# first client is modifying `msg`
clients.append(asyncio.create_task(handle_read(reader, addr)))
else:
# all other clients are receiving `msg` every 3 seconds
clients.append(asyncio.create_task(handle_write(writer, addr)))
await clients[-1]
async def run_server():
server = await asyncio.start_server(handle_client, "0.0.0.0", 8686)
async with server:
await server.serve_forever()
asyncio.run(run_server())
The first client is special - is modifying the msg
. All other clients are receiving every 3 seconds the msg
the first client sent.
Answered By - Andrej Kesely
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.