Comment puis-je trouver dans C un port libre?
Le système d'exploitation est Linux.
J'ai un serveur de processus qui peuvent changer son port en temps réel. Cependant, j'aimerais savoir à l'avance si un port est gratuit avant la liaison.
Scénario: le Serveur se lie localhost:5000 et reçoit une demande de lier à localhost:6000. Le serveur doit vérifier si le port est gratuit. Cette question, on cherche des réponses qui fournissent une routine qui vérifie si un port est gratuit ou pas.
Pour l'enregistrement, je suis la retouche de mes question avec un fragment de code qui vérifie si un port est gratuit à utiliser. Cela ne signifie pas qu'il sera utilisé. Le code ci-dessous réponse à la question "si le port est disponible dès maintenant", il ne l'utilise pas. Ouvre un socket, vérifier si bind retourne EADDRINUSE et ferme le socket.
#include <iostream>
#include <sys/socket.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <errno.h>
int main(int argc, char **argv) {
struct sockaddr_in serv_addr;
if( argc < 2 )
return 0;
int port = atoi(argv[1]);
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if( sockfd < 0 ) {
printf("socket error\n");
return 0;
} else {
printf("Opened fd %d\n", sockfd);
}
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(port);
if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
if( errno == EADDRINUSE )
{
printf("the port is not available. already to other process\n");
} else {
printf("could not bind to process (%d) %s\n", errno, strerror(errno));
}
}
if (close (sockfd) < 0 ) {
printf("did not close fd: %s\n", strerror(errno));
return errno;
}
return 0;
}
Voici quelques exemples de pistes (sorties partielles)
[bash{1051}{51}]:[~/some_sources/checkbind]::./a.out 41067
the port is not available. already to other process
[bash{1052}{52}]:[~/some_sources/checkbind]::./a.out 22
could not bind to process (13) Permission denied
[bash{1053}{53}]:[~/some_sources/checkbind]::./a.out 22000
Opened fd 3
source d'informationauteur cateof
Vous devez vous connecter pour publier un commentaire.
C'est une évidence condition de coursepuisque d'autres processus sur votre système peut être contraignant pour les ports en parallèle. Donc, toute solution que vous trouverez seront imparfaite, et vous encore besoin de l'écrire en fonction de la "essayer de
bind()
si elle omet de se choisir un nouveau numéro de port et essayez à nouveau".Si votre serveur a été dit ce port à utiliser, il suffit
bind()
. Sérieusement.Bien sûr, vous pourriez analyser
/proc/net/tcp
et voir si le port est en cours d'utilisation. Mais alors quoi? Vous avez toujours besoin d'appelerbind()
maintenant que vous savez que votre port est gratuit, et il vous dira si le port était gratuit puis de toute façon, et donc il n'y a pas lieu de ramper à travers/proc/net/tcp
et faire tout ce qui est (lent!) chaîne de production et de l'analyse et de l'extra noyau voyages grâce à des pas-très-bien optimisé (lire: super lent par rapport àbind()
) de diagnostic chemins, juste pour obtenir de l'information qui pourrait bien être obsolète avant même d'avoir fini l'analyse. Donc appelez simplementbind()
et d'être heureux.J'ai lutté avec moi-même et ont légèrement modifié votre code.
La solution est de mettre
serv_addr.sin_port = 0
(affectation automatique de port).Note Dans le
bind()
et lagetsockname()
lignes il y a d'impur jette desockaddr_in
àsockaddr
. Je l'ai vu faire beaucoup d'endroits et je suis à la recherche d'une solution plus sûre.Programme de sortie de