Local Host Fails to Initiate Too Many Connections

Asked 2 years ago, Updated 2 years ago, 409 views

Lubuntu 20.04 64bit
node.js16.17.1
python 3.8.10

(1) Using node.js, launch the HTTP server in the http-server package on port 8000 in the appropriate directory.

npx http-server --port8000

(2) Prepare the python script named client.py

import asyncio

async def client():
    reader, writer = wait asyncio.open_connection ('127.0.0.1', 8000)
    writer.write(f'GET/HTTP/1.1\r\nHost:127.0.0.1\r\nConnection:keep-alive\r\n\r\n'.encode())
    wait writer.drain()
    data = wait reader.read (10240)
    writer.close()
    wait writer.wait_closed()

async def clients (N):
    wait asyncio.gather(*[client() for_inrange(N)])

asyncio.run(clients(0x10000))

(3) Run the script prepared in (2) as follows.

 python3 client.py; ss-an | grep8000 | grep TIME-WAIT | wc-l

<addition:running on ulimit-n 1048576

(4) After a few minutes, the following error will be displayed on the execution terminal of (2)

Traceback (most recent call last):
  File "client.py", line 14, in <module>
    asyncio.run(clients(0x10000))
  File"/usr/lib/python 3.8/asyncio/runners.py", line 44, in run
    return loop.run_until_complete(main)
  File"/usr/lib/python 3.8/asyncio/base_events.py", line616, in run_until_complete
    return future.result()
  File "client.py", line 12, clients
    wait asyncio.gather(*[client() for_inrange(N)])
  File "client.py", line 4, client
    reader, writer = wait asyncio.open_connection ('127.0.0.1', 8000)
  File"/usr/lib/python 3.8/asyncio/streams.py", line 52, in open_connection
    transport,_=wait loop.create_connection(
  File"/usr/lib/python 3.8/asyncio/base_events.py", line 1025, create_connection
    raise exceptions [0]
  File"/usr/lib/python 3.8/asyncio/base_events.py", line 1010, create_connection
    sock = wait self._connect_sock(
  File"/usr/lib/python 3.8/asyncio/base_events.py", line 924, in_connect_sock
    wait self.sock_connect(sock, address)
  File"/usr/lib/python 3.8/asyncio/selector_events.py", line 496, insock_connect
    return wait ft
  File"/usr/lib/python 3.8/asyncio/selector_events.py", line 501, in_sock_connect
    sock.connect (address)
OSError: [Errno99] Cannot assign requested address
16383

What is happening in this error?

I rewritten it.

import asyncio

async def client (id):
    print(f'{id}:started')
    reader, writer = wait asyncio.open_connection ('127.0.0.1', 8000)
    writer.write(f'GET/HTTP/1.1\r\nHost:127.0.0.1\r\nConnection:keep-alive\r\n\r\n'.encode())
    wait writer.drain()
    # print(f'{id}:before read')
    data = wait reader.read (10240)
    # print(data)
    # print(f'{id}:after read')
    writer.close()
    wait writer.wait_closed()
    print(f'{id}:finished')

async def clients (N):
    wait asyncio.gather (*[client(i) for i in range(N)])

asyncio.run(clients(0x10000))

python linux network

2022-10-23 00:01

1 Answers

asyncio.open_connection('127.0.0.1',8000) specifies the port number to which you want to connect, but does not specify the port number that you want to use.In such cases, TCP/IP uses a port number called dynamic or ephemeral port.

$sysctl net.ipv4.ip_local_port_range
net.ipv4.ip_local_port_range=3276860999

Your machine has the above range and only has approximately 28,000 ports.

Apart from that, TCP/IP is a communication with the other party, and even if you end up using it, the other party may send you additional data.If you assign a port to another program in that state, later programs will receive incorrect data.The cooldown time to avoid such problems is TIME_WAIT and cannot be reused for a certain period of time.

$sysctl net.ipv4.tcp_fin_timeout
net.ipv4.tcp_fin_timeout=60

I was not supposed to reuse my machine for 60 seconds.

These two things can happen, and 65,536 attempts to connect, such as asyncio.run(clients(0x10000)), do not get any available ports and cannot start processing.


2022-10-23 00:01

If you have any answers or tips


© 2024 OneMinuteCode. All rights reserved.