C programmation socket: connect() se bloque
Salut à tous, je suis sur le point de déchirer mes cheveux. J'ai ce client qui tente de se connecter à un serveur, tout semble aller pour le mieux, à l'aide de gethostbyname()
, socket()
, bind()
, mais lorsque j'essaie de connect()
il se contente d'être là et le serveur ne voit rien de la part du client. Je sais que le serveur fonctionne, car un autre client (C) peut se connecter à l'amende juste. Quelles sont les causes du serveur pour ne pas voir cette connexion entrante? Je suis à la fin de mes esprits ici. Les deux clients différents, se ressemblent trop, donc je suis encore plus perdu.
if (argc == 2) {
host = argv[1]; //server address
}
else {
printf("plz read the manual\n");
exit(1);
}
hserver = gethostbyname(host);
if (hserver) {
printf("host found: %p\n", hserver);
printf("host found: %s\n", hserver->h_name );
}
else {
printf("host not found\n");
exit(1);
}
bzero((char * ) &server_address, sizeof(server_address)); //copy zeroes into string
server_address.sin_family = AF_INET;
server_address.sin_addr.s_addr = htonl(hserver->h_addr);
server_address.sin_port = htons(SERVER_PORT);
bzero((char * ) &client_address, sizeof(client_address)); //copy zeroes into string
client_address.sin_family = AF_INET;
client_address.sin_addr.s_addr = htonl(INADDR_ANY);
client_address.sin_port = htons(SERVER_PORT);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
exit(1);
else {
printf("socket is opened: %i \n", sockfd);
info.sock_fd = sockfd;
rv = fcntl(sockfd, F_SETFL, O_NONBLOCK); //socket set to NONBLOCK
if(rv < 0)
printf("nonblock failed: %i %s\n", errno, strerror(errno));
else
printf("socket is set nonblock\n");
}
timeout.tv_sec = 0; //seconds
timeout.tv_usec = 500000; //micro seconds ( 0.5 seconds)
setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(struct timeval));
rv = bind(sockfd, (struct sockaddr *) &client_address, sizeof(client_address));
if (rv < 0) {
printf("MAIN: ERROR bind() %i: %s\n", errno, strerror(errno));
exit(1);
}
else
printf("socket is bound\n");
rv = connect(sockfd, (struct sockaddr *) &server_address, sizeof(server_address));
printf("rv = %i\n", rv);
if (rv < 0) {
printf("MAIN: ERROR connect() %i: %s\n", errno, strerror(errno));
exit(1);
}
else
printf("connected\n");
Des pensées ou des idées sont profondément grandement humongously apprécié.
-Fourier
EDIT:
Si la prise n'est PAS défini sur non-bloc, puis il se bloque.
Si la socket est définie sur non-bloc, puis-je obtenir ERROR connect() 115: Operation now in progress
[EINPROGRESS]
O_NONBLOCK est défini pour le fichier descripteur de la socket et la connexion ne peut pas être immédiatement établie, la connexion doit être établie de manière asynchrone.
Je tiens également à mentionner que le serveur et le client sont en cours d'exécution sur les ordinateurs à côté les uns des autres, reliés par un routeur.
errno est de 115 mais c'est résolu maintenant. Merci beaucoup obligé
Stupide pensée: le serveur de permettre à plusieurs clients qui se connectent? Après le "accept()" est-ce frayer un fil, une childprocess ou utiliser select() pour redémarrer accepter un require() les connexions entrantes ET gérer le trafic du client qui vient de connecté?
Haavee: oui le serveur permet à plusieurs clients. J'ai un thread qui est dédié à vérifier pour les connexions entrantes à l'aide de
select()
.OriginalL'auteur Fantastic Fourier | 2010-04-16
Vous devez vous connecter pour publier un commentaire.
La
gethostbyname()
fonction donne les adresses dans l'ordre des octets de réseau, de sorte que vous n'avez pas besoin de passer à travers lahtonl()
. Aussi, lehostent->h_addr
entrée est un pointeur vers l'adresse. Remplacer cette ligne:avec:
Bien "connexion refusée" est assez claire. Peut-être que votre
SERVER_PORT
est aussi une mauvaise.oui, je ne peux pas croire que je n'ai pas l'attraper. 12345 et 12346 regardé sacrément similaire grâce à mon inexistant vue.
OriginalL'auteur caf
Je vois que vous définissez votre prise en O_NONBLOCK mode.
Ainsi connecter doit retourner -1 et définir
errno
à EAGAIN selon la page de man de se connecter.Vous pouvez alors savoir quand la connexion a réussi à l'aide de
select()
sur le socket.C'est un schéma très commun pour contrôler le délai d'attente de connexion (parce que
select()
doivent être nourris avec un délai d'attente).OriginalL'auteur ereOn
Vérifier si vous pouvez vous connecter avec le programme
telnet
(il accepte un nom de serveur et le numéro de port). Si cela fonctionne, le bug doit être dans votre code. Si telnet aussi se bloque, puis vérifiez vos paramètres de pare-feu.OriginalL'auteur Aaron Digulla
Si vous voulez connecter deux fois à partir de la même machine, je peux voir la cause de votre problème.
Vous sont contraignantes pour l'clientsocket. Votre code lie la client prise très précisément à un port fixe (le port du serveur). Cela laisse à l'O/S n'est PAS libre de choisir un port disponible pour faire le lien. Si un processus a le port alloué (il a réussi lié() et connecté() pour le serveur), puis les autres processus ne peut pas utiliser le même port.
Si il n'y a pas de raison convaincante pour envoyer le trafic à PARTIR d'un port spécifique, laissez-le S/S trouver un port disponible en changeant cette ligne
à
bind()
serait un échec (et l'OP a la vérification des erreurs sur cet appel).Serait intéressant d'obtenir la valeur de SO_REUSEADDR. Si elle est définie sur true("1"), alors que le bind() ne manquera pas.
OriginalL'auteur haavee