En gros :
- sans SO_REUSEADDR, tu te prends un EADDRINUSE en TCP/UDP si tu te bindes au même couple (interface, port)
- avec SO_REUSEADDR sur chaque socket, en UDP tu peux te binder plusieurs fois au même (interface, port), mais le comportement n'est déterministe que si tu reçois du broadcast/multicast (tous les socket srecoivent les données), en unicast il n'y a aucune garantie, généralement le premier socket va tout recevoir, et les autres rien
- en TCP, avec SO_REUSEADDR sur chaque socket, tu peux te binder plusieurs fois seulement si l'autre socket n'est pas en LISTEN (puisque plusieurs bind sur le même port alors qu'une communication unicast est établie n'a pas de sens)
Windows semble autoriser un bind multiple en TCP même si l'autre socket est en LISTEN, enfin je n'ai pas de Windows sous la main, et si c'est le cas ce n'est absolument pas normal/standard.
Enfin, l'intérêt principal de SO_REUSEADDR c'est de pourvoir réutiliser une adresse en TIME-WAIT.
J'ai laissé de côté SO_REUSEPORT parce qu'il n'est plus utilisé sous Linux:
/usr/include/asm-generic/socket.h:#define SO_REUSEADDR 2
/usr/include/asm-generic/socket.h:/* To add :#define SO_REUSEPORT 15 */
[^] # Re: SO_REUSEADDR et SO_REUSEPORT
Posté par neologix . En réponse au message Science-fiction : 2 applications sur le même port ?. Évalué à 5.
Un peu plus de détails, avec un petit script pour expérimenter :
"""
import socket
import sys
import optparse
parser = optparse.OptionParser()
parser.add_option('-P', dest='protocol', default='tcp')
parser.add_option('-p', dest='port', type='int', default=4242)
parser.add_option('-r', dest='reuse', action='store_true', default=False)
options, args = parser.parse_args()
if options.protocol == 'udp':
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
else:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
if options.reuse:
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
try:
s.bind(('', options.port))
if options.protocol == 'tcp':
s.listen(3)
raw_input()
finally:
s.close()
"""
En gros :
- sans SO_REUSEADDR, tu te prends un EADDRINUSE en TCP/UDP si tu te bindes au même couple (interface, port)
- avec SO_REUSEADDR sur chaque socket, en UDP tu peux te binder plusieurs fois au même (interface, port), mais le comportement n'est déterministe que si tu reçois du broadcast/multicast (tous les socket srecoivent les données), en unicast il n'y a aucune garantie, généralement le premier socket va tout recevoir, et les autres rien
- en TCP, avec SO_REUSEADDR sur chaque socket, tu peux te binder plusieurs fois seulement si l'autre socket n'est pas en LISTEN (puisque plusieurs bind sur le même port alors qu'une communication unicast est établie n'a pas de sens)
Windows semble autoriser un bind multiple en TCP même si l'autre socket est en LISTEN, enfin je n'ai pas de Windows sous la main, et si c'est le cas ce n'est absolument pas normal/standard.
Enfin, l'intérêt principal de SO_REUSEADDR c'est de pourvoir réutiliser une adresse en TIME-WAIT.
J'ai laissé de côté SO_REUSEPORT parce qu'il n'est plus utilisé sous Linux:
/usr/include/asm-generic/socket.h:#define SO_REUSEADDR 2
/usr/include/asm-generic/socket.h:/* To add :#define SO_REUSEPORT 15 */