Comment vérifier l’accessibilité d’un port TCP en Python (Synchrone & Asynchrone)
- 22 décembre 2025
- 10 mins de lecture
- Programmation python , Débogage et troubleshooting
Table des matières
Rien ne bloque un déploiement plus vite qu’une erreur « Connection Refused » que vous n’avez pas vue venir. Que vous déboguiez un changement silencieux de firewall ou que vous supervisiez un microservice, vérifier l’accessibilité TCP est la première ligne de défense du dépannage réseau.
Une méthode courante consiste à vérifier si un service TCP sur un serveur distant accepte les connexions.
Dans cet article, nous allons voir comment implémenter une vérification simple de l’accessibilité d’un service TCP distant en Python, en utilisant des approches synchrones et asynchrones.
À la fin, vous saurez comment créer ces vérifications, quand les utiliser, et pourquoi elles sont essentielles.
​
Pourquoi vérifier l’accessibilité TCP ?
Concrètement, vérifier l’accessibilité TCP consiste à tenter d’établir une connexion vers un port précis sur un serveur distant. Si la connexion réussit, le service est accessible. Si elle échoue (timeout, connexion refusée, etc.), le service est indisponible ou inaccessible.
C’est utile pour :
- Superviser la disponibilité des services.
- Vérifier des configurations réseau ou firewall.
- Déboguer des problèmes de connexion dans des systèmes distribués.
Si vous utilisez un terminal Linux dans un conteneur restreint, vous pouvez également tester vos ports via les fonctionnalités natives de Bash. Consultez mon guide sur les 5 commandes essentielles de débogage réseau sous Linux minimal pour une solution rapide et sans installation.
Voyons maintenant comment l’implémenter sans dépendre d’outils ou de bibliothèques tierces.
Bulletin d'information
Abonnez-vous à notre bulletin d'information et restez informé(e).
​
Sans outils ou bibliothèques tierces
En Python, la bibliothèque standard socket fournit tout le nécessaire pour vérifier l’accessibilité TCP.
Nous allons voir deux approches : synchrone (bloquante) et asynchrone (non bloquante).
​
Implémentation synchrone
L’approche synchrone est simple et facile à comprendre. Elle tente de créer une connexion vers le service distant et réussit ou échoue après un délai.
Voici le code :
1import socket
2
3def check_port_reachable(address: str, port: int, timeout_sec: float = 3) -> bool:
4 """
5 Vérifie que le couple (adresse, port) est accessible via une connexion TCP.
6 Retourne True si accessible, sinon False.
7
8 Parameters
9 ----------
10 address : str
11 Adresse IP ou nom d'hôte du service distant.
12 port : int
13 Numéro du port à vérifier.
14 timeout_sec : int
15 Délai maximal de la tentative de connexion, en secondes.
16
17 Returns
18 ------
19 bool
20 True si le port est accessible, False sinon.
21 """
22 # Pour IPv6, utiliser `AF_INET6` au lieu de `AF_INET`
23 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
24 sock.settimeout(timeout_sec)
25
26 try:
27 sock.connect((address, port))
28 sock.shutdown(socket.SHUT_RDWR)
29 sock.close()
30 return True
31 except (socket.timeout, socket.error):
32 sock.close()
33 return False
Fonctionnement
- Un socket TCP est créé via
socket.socket. - La méthode
connecttente de se connecter à(adresse, port)dans le délaitimeout_sec. - En cas de succès, la connexion est fermée proprement et la fonction retourne
True. En cas d’échec, elle retourneFalse.
Version alternative avec connect_ex
Une légère variante utilise connect_ex, qui retourne 0 si la connexion réussit, ou un code d’erreur sinon :
1def check_port_with_connect_ex(address: str, port: int, timeout_sec: float = 3) -> bool:
2 try:
3 # Pour IPv6, utiliser `AF_INET6` au lieu de `AF_INET`
4 with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
5 sock.settimeout(timeout_sec)
6 if sock.connect_ex((address, port)) == 0:
7 return True
8 return False
9 except OSError:
10 return False
Cette version gère plus proprement les erreurs (IP invalide, port incorrect) et évite de capturer des exceptions trop génériques.
Tip
Si vous comparez cette version avec check_port_reachable, vous verrez que j’utilise l’instruction with lors de l’ouverture du socket.
Cela garantit la fermeture automatique du socket à la sortie du bloc with.
​
Implémentation asynchrone
Pour les applications nécessitant des entrées/sorties non bloquantes, notamment lorsqu’il faut gérer de nombreuses connexions, l’approche asynchrone avec asyncio est plus efficace.
Voici une implémentation asynchrone :
1import asyncio
2
3async def check_port_reachable_async(address, port, timeout_sec=3):
4 """
5 Vérifie de manière asynchrone si le couple (adresse, port) est accessible via TCP.
6 Retourne True si accessible, sinon False.
7
8 Parameters
9 ----------
10 address : str
11 Adresse IP ou nom d'hôte du service distant.
12 port : int
13 Numéro du port à vérifier.
14 timeout_sec : int
15 Délai maximal de la tentative de connexion, en secondes.
16
17 Returns
18 ------
19 bool
20 True si le port est accessible, False sinon.
21 """
22 writer = None
23 try:
24 # Tentative de connexion asynchrone
25 reader, writer = await asyncio.wait_for(
26 asyncio.open_connection(address, port),
27 timeout=timeout_sec
28 )
29 # Fermeture propre de la connexion
30 writer.close()
31 await writer.wait_closed()
32 return True
33 except (TimeoutError, asyncio.TimeoutError, ConnectionRefusedError, OSError):
34 return False
35 finally:
36 if writer:
37 writer.close()
38 try:
39 await writer.wait_closed() # ajouté en Python 3.7
40 except (OSError, AttributeError):
41 pass # Déjà fermé
Fonctionnement
asyncio.open_connectiontente d’établir une connexion TCP de façon asynchrone.- En cas de succès, la connexion est fermée et
Trueest retourné. - En cas de timeout ou de refus, la fonction retourne
False.
Pourquoi utiliser l’asynchrone ?
Si vous devez vérifier plusieurs services en parallèle, l’asynchrone est préférable.
Plutôt que d’attendre chaque connexion l’une après l’autre, asyncio permet de lancer toutes les vérifications simultanément.
Les gains de performance sont importants pour la supervision de clusters ou de systèmes distribués.
Bulletin d'information
Abonnez-vous à notre bulletin d'information et restez informé(e).
​
Quand utiliser un mécanisme de retry avec backoff
Des problèmes réseau temporaires peuvent provoquer des échecs ponctuels. Dans ces cas, il est utile de réessayer la vérification plusieurs fois avant d’abandonner. On peut utiliser une boucle simple.
Pour des tâches simples, une boucle suffit. En production, il faut aller plus loin. Des stratégies comme le backoff exponentiel et le jitter évitent de surcharger les systèmes.
Voici un exemple simple avec délai constant :
- Synchrone
- Asynchrone
1import time
2
3def check_with_retries(address, port, retries=3, delay_sec=2):
4 for attempt in range(retries):
5 if check_port_reachable(address, port):
6 return True
7 time.sleep(delay_sec)
8 return False
1import asyncio
2
3async def check_with_retries_async(address, port, retries=3, delay_sec=2):
4 for attempt in range(retries):
5 if await check_port_reachable_async(address, port):
6 return True
7 await asyncio.sleep(delay_sec)
8 return False
Cette fonction tente la vérification jusqu’à 3 fois, avec 2 secondes d’attente entre chaque essai.
​
Causes courantes d’inaccessibilité
Plusieurs facteurs peuvent rendre un service distant inaccessible :
- Service arrêté : le service ne tourne pas sur la machine distante.
- Problèmes réseau : routage, pertes de paquets, DNS défaillant.
- Adresse ou port incorrect : vérifiez l’IP/le nom d’hôte et le port.
- Restrictions firewall : les connexions entrantes ou sortantes sont bloquées.
- Blocage silencieux des paquets : certains firewalls configurés en mode DROP ne renvoient pas de refus. Le script attend alors jusqu’à la fin du
timeout_secavant d’échouer.
Comprendre la raison de l’échec est essentiel pour le corriger. Est-ce une erreur temporaire ou une panne complète du système ? Je détaille ces différences clés dans l’Explication illustrée des notions de Fault, Error, Failure, Bug et Defect en logiciel.
​
Utilisation d’outils et bibliothèques tierces
La bibliothèque standard de Python est puissante, mais les outils tiers simplifient les vérifications complexes ou les besoins de scan réseau.
Ils offrent souvent des fonctionnalités avancées comme l’identification de services, le multithreading, ou des mécanismes de retry plus robustes.
Voici une sélection de bibliothèques populaires, suivie d’un tableau comparatif.
​
Outils et bibliothèques populaires
-
Scapy : bibliothèque puissante de manipulation de paquets réseau. Adaptée au scan de ports et à l’analyse de protocoles.
-
PortScan : bibliothèque Python légère pour scanner des ports et services distants. Simple et rapide.
-
TPScanner : scanner de ports TCP en Python, facilement adaptable à plusieurs ports.
-
python-nmap : wrapper Python de Nmap. Permet le scan de ports, la détection de services et l’empreinte OS.
-
PyPortScanner : bibliothèque simple pour vérifier rapidement l’ouverture de ports TCP.
​
Récapitulatif des bibliothèques tierces
| Bibliothèque | Fonctionnalités | Complexité d’installation | Cas d’usage idéal |
|---|---|---|---|
| Scapy | Manipulation de paquets, scan, tests de sécurité | Moyenne | Tests réseau avancés |
| PortScan | Scan TCP basique, léger, rapide | Faible | Vérifications simples et rapides |
| TPScanner | Scan multi-ports, adaptable, open-source | Faible | Scan léger de plusieurs ports |
| python-nmap | Scan réseau complet (services, OS, etc.) | Moyenne (Nmap requis) | Analyse réseau approfondie |
| PyPortScanner | Scan TCP simple et léger | Faible | Vérifications rapides de ports |
Ces bibliothèques permettent de choisir l’outil le plus adapté selon vos besoins, du simple test de port à l’analyse réseau avancée.
Bulletin d'information
Abonnez-vous à notre bulletin d'information et restez informé(e).
​
Foire aux questions
- Quelle est la différence entre un ping et une vérification TCP ?
- Le ping utilise ICMP pour vérifier si une machine est joignable, mais il ne dit rien sur un service précis. Une vérification TCP confirme qu’un port spécifique écoute réellement et accepte des connexions.
- Est-ce que la vérification ouvre réellement une session ?
- Oui. Ces méthodes réalisent un « three-way handshake ».
La connexion est immédiatement fermée afin de limiter l’impact sur le service distant.
Techniquement,
socket.connecteffectue un three-way handshake complèt sans envoyer de données applicatives, ce qui reste très léger et sûr pour une supervision fréquente.
​
Conclusion
Vérifier l’accessibilité d’un service TCP distant est une tâche essentielle dans de nombreux contextes réseau. Grâce aux bibliothèques intégrées de Python, il est facile d’implémenter des approches synchrones et asynchrones.
Selon votre cas d’usage, vous pouvez ajouter des mécanismes de retry ou utiliser des outils tiers pour simplifier le processus.
Ces techniques facilitent la gestion des serveurs et le débogage des problèmes de connectivité. Elles constituent la première étape pour garantir que vos applications restent accessibles et fonctionnelles.