Lors de la liaison d'un client TCP socket à un port local spécifique avec Winsock, SO_REUSEADDR n'a aucun effet
Je suis de la liaison d'un client socket TCP sur un port local spécifique. Pour gérer la situation où la prise reste en TIME_WAIT
de l'état pour un certain temps, j'utilise setsockopt()
avec SO_REUSEADDR
sur un socket.
Il fonctionne sur Linux, mais ne fonctionne pas sur Windows, j'obtiens WSAEADDRINUSE
sur connect()
appel lors de la connexion précédente est encore en TIME_WAIT
.
MSDN n'est pas exactement clair ce qui doit se passer avec les sockets client:
[...] Pour des applications de serveur qui ont besoin de lier prises multiples pour le même numéro de port, pensez à utiliser
setsockopt
(SO_REUSEADDR
). Les applications clientes doivent habituellement pas appeler bind—connecter choisit automatiquement un port inutilisé. [...]
Comment puis-je éviter cela?
c'est une exigence du système externe, je suis l'interfaçage avec, et il est impossible de l'éviter.
pouvez-vous partager un code de travail pièce de liaison d'un socket client sur Linux?
ma question: stackoverflow.com/questions/4711608/...
OriginalL'auteur Alex B | 2010-04-09
Vous devez vous connecter pour publier un commentaire.
Lorsque vous créez un socket avec
socket()
, il ne dispose que d'un type et d'un protocole de famille. L'idéal est debind()
à une adresse locale:port trop.L'erreur que vous avez mentionné, qui se fait normalement lors de la dernière connexion à l'hôte:port n'ai pas eu un arrêt normal (FIN/ACK FIN/ACK). Dans ces cas, la prise de séjours dans
TIME_WAIT
état pendant une certaine période de temps (OS dépendante, mais réglable).Ce qui se passe alors, c'est quand vous essayez de
connect()
pour le même accueil et le même port, il utilise la valeur par défaut de la prise de nom/adresse/port/etc, mais cette combinaison est déjà en cours d'utilisation par votre zombie socket. Pour éviter cela, vous pouvez modifier l'adresse locale:port utilisé pour établir la connexion en appelantbind()
après la création de la socket, en fournissant lessockaddr
struct rempli avec votre adresse et un aléatoire port.Mise à JOUR: à l'aide d'un port local est une exigence, d'envisager de mettre
SO_LINGER
avecl_onoff=1
etl_linger=0
de sorte que votre prise de ne pas bloquer surclose
/closesocket
, il sera tout simplement ignorer les données en file d'attente et (espérons-le) à proximité de la fd. Comme un dernier recours, vous pouvez ajuster laTIME_WAIT
retard en changeant la valeur de cette clé de registre (très déconseillé!):Est le réglage du TIME_WAIT à une valeur inférieure acceptable?
À mon humble avis il ne devrait jamais être la première chose...
ne soyez pas timide, nous apprécions les suggestions 🙂
Btw, j'ai mis à jour les dernières lignes de mentionner SO_LINGER. Il est venu à l'esprit après @Len commentaire.
OriginalL'auteur jweyrich
Vous n'avez pas spécifié de quel Windows plate-forme que vous utilisez, qui peuvent affecter des choses comme le principal de sécurité que vous êtes en cours d'exécution en vertu de l' (c'est à dire vous êtes admin?)...
Cela peut aider: http://blogs.msdn.com/wndp/archive/2005/08/03/Anthony-Jones.aspx
OriginalL'auteur Len Holgate
Être prudent dans la liaison du port local de ne PAS utiliser l'adresse de bouclage "127.0.0.1", ou vous obtiendrez des délais de connexion. Mieux vaut ne pas remplir la sa_loc.sin_addr.s_addr à tous - qui fonctionne très bien.
OriginalL'auteur Pierre