I have a raspberry pi, and its too slow for running a http server and software pwm on its GPIO pins, so I made a custom "protocol" to send requests to it. The problem is that it uses raw socket, and the server side is made with asyncio, but with that I need to create a new socket connection every time I want to send a request. (I need to send ~165 requests per second). But after I exceed ~15000 requests, it starts saying Error: [WinError 10048] Only one usage of each socket address (protocol/network address/port) is normally permitted.ห and I can't figure out why...
#๐ Can't exceed ~15000 requests to a raw socket server
22 messages ยท Page 1 of 1 (latest)
@wispy lotus
Remember to:
- Ask your Python question, not if you can ask or if there's an expert who can help.
- Show a code sample as text (rather than a screenshot) and the error message, if you've got one.
- Explain what you expect to happen and what actually happens.
:warning: Do not pip install anything that isn't related to your question, especially if asked to over DMs.
Closes after a period of inactivity, or when you send !close.
Can't exceed ~15000 requests to a raw socket server
You could reuse the socket?
And also are you closing the sockets when you're finished with them?
how would I do that? I dont really know how to use raw sockets with asyncio
here is my current server code:
import asyncio
def parse_packet(data):
return None, None, "OK"
async def handle_client(reader, writer):
global counter
try:
transport = writer.get_extra_info('peername')
client_ip = transport[0] if transport else None
data = await reader.read(32768)
rgb, json_dict, return_message = parse_packet(data)
print(f"FROM {client_ip} --> {return_message}")
counter += 1
print(counter)
writer.write(return_message.encode())
await writer.drain()
except Exception as e:
print(f"Error: {e}")
finally:
writer.close()
await writer.wait_closed()
async def main(host="0.0.0.0", port=8888):
server = await asyncio.start_server(handle_client, host, port)interfaces, port 8888
async with server:
await server.serve_forever()
asyncio.run(main())
yes, it should close the sockets
And also I'm not using the socket module because as far as I know that would make me use a while True loop to check for packets and it messes up the pwm
Is your client closing connections?
You should probably use a while True loop in your handle_client, and send the length of the message followed by the message on the socket
Then you only need to open one socket from your windows machine
yes, my client is closing connections. However I found why its saying the error...
I'm running out of local ports
I ran netstat -ano|findstr 8888
and the output was (after about a minute):
basically listing all the possible ephemeral ports on windows
Show your windows client source code?
import json
import socket
import time
import re
SERVER_ADDRESS = '192.168.0.46'
SERVER_PORT = 8888
def is_rgb(s):
pattern = re.compile(r'^(?:#)?[0-9A-Fa-f]{6}')
return bool(pattern.match(s))
def rgb_to_bytes(rgb_string):
if is_rgb(rgb_string):
pairs = [rgb_string[i:i + 2] for i in range(0, len(rgb_string), 2)]
bytes_list = [bytes.fromhex(pair) for pair in pairs]
result = b''.join(bytes_list)
return result
else:
raise ValueError(f"{rgb_string} is not a valid RGB code")
def send_data(rgb_data, json_dict):
START_WORD = b"\x02\x7e\x30\x06"
END_WORD = b"\x03\x7e\x30\x06"
JSON_START_WORD = b"\x02json"
JSON_END_WORD = b"\x03json"
PADDING = b"\x00\x00\x00\x00\x00\x00"
try:
# Create a socket object
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# Connect to the server
s.connect((SERVER_ADDRESS, SERVER_PORT))
# Send data to the server
s.send(START_WORD+PADDING+rgb_to_bytes(rgb_data)+JSON_START_WORD+json.dumps(json_dict).encode()+JSON_END_WORD+END_WORD)
response = s.recv(1024)
print(f"Response from server: {response.decode()}")
s.close()
time.sleep(0.005)
except Exception as e:
print(f"Error: {e}")
if __name__ == "__main__":
st = time.time()
counter = 0
while time.time() < st + 120:
counter += 1
send_data("696969", {"test-json": "1234526789213456789123456789"})
print(counter)
Why are you setting SO_REUSEADDR?
I just copied that line hoping it would fix it, but it didnt
Use with socket.create_connection((SERVER_ADDRESS, SERVER_PORT)) as s:
got the same error after 15000 requests
Show the updated code?
This help channel has been closed and it's no longer possible to send messages here. If your question wasn't answered, feel free to create a new post in #1035199133436354600. To maximize your chances of getting a response, check out this guide on asking good questions.