`asyncio` does not set `TCP_NODELAY` on macOS
Dieses Issue hat noch niemand übernommen.
- Vorherrschende Sprache
- Python
- Sterne
- 77.2k
- Forks
- 35.9k
- PR-Merge-Kennzahlen
- PR-Kennzahlen ausstehend
Beschreibung
Bug report
Bug description:
On macOS, asyncio server silently skips setting TCP_NODELAY on accepted connections.
Reproduce
import asyncio
import socket
async def main():
async def on_connect(reader, writer):
sock = writer.transport.get_extra_info('socket')
nodelay = sock.getsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY)
print(f'server side: sock.proto={sock.proto} TCP_NODELAY={nodelay}')
writer.close()
await writer.wait_closed()
srv.close()
srv = await asyncio.start_server(on_connect, '127.0.0.1', 0)
port = srv.sockets[0].getsockname()[1]
reader, writer = await asyncio.open_connection('127.0.0.1', port)
sock = writer.transport.get_extra_info('socket')
nodelay = sock.getsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY)
print(f'client side: sock.proto={sock.proto} TCP_NODELAY={nodelay}')
await asyncio.sleep(0.1)
writer.close()
await writer.wait_closed()
await srv.wait_closed()
asyncio.run(main())
| Platform | Side | sock.proto |
TCP_NODELAY |
|---|---|---|---|
| Linux | client | 6 ✅ | 1 ✅ |
| Linux | server | 6 ✅ | 1 ✅ |
| macOS | client | 6 ✅ | 4 ✅ |
| macOS | server | 0 ❌ | 0 ❌ |
Cause
In socket.__init__, CPython tries to detect proto with getsockopt + SO_PROTOCOL and falls back to 0 if SO_PROTOCOL is not supported, which is the case on macOS.
While socket.accept does pass in the proto from listening socket, it is silently overridden to zero by the above logic.
https://github.com/python/cpython/blob/82767780f8de2fc492567ceb6a590101ae3b19ad/Lib/socket.py#L300
asyncio sets TCP_NODELAY only when sock.proto == socket.IPPROTO_TCP, but it is 0 on macOS for the above reason.
Client socket works fine because no fd is passed to socket.__init__ so the proto detection doesn't happen.
CPython versions tested on:
3.13
Operating systems tested on:
macOS, Linux
Linked PRs
- gh-148784
Beitragsleitfaden
Erste Schritte
- Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
- Forke das Repository und arbeite in einem Branch.
- Öffne einen Pull Request, der die Issue-Nummer nennt.
Rechercherichtung
Überprüfe die verknüpfte Implementierung in Modules/socketmodule.c, Lib/socket.py und Lib/asyncio/base_events.py, beginnend mit socket.init und socket.accept. Prüfe vor Beginn PR gh-148784; abgeschlossen ist die Aufgabe, wenn akzeptierte macOS-Verbindungen die erwarteten TCP-Protokollinformationen erhalten und asyncio TCP_NODELAY konsistent mit Clientverbindungen setzt.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Bewertung
- Tech-Stack
- c, python
- Bereich
- networking
- Issue-Typ
- Bug
- Schwierigkeit
- 4/5
- Geschätzter Aufwand
- 3-5 Tage
- Aktivitätsstatus
- Veraltet
- Klarheit
- Klar beschrieben
- Anfängerfreundlichkeit
- 25/100