Socket de Programmation C/C++ - fonction recv se bloque?
Ma fonction recv se bloque lors de l'obtention de reponse du serveur.
Côté Client code en c/c++:
void sockStuff() {
int sock, bytes_recieved,bytes_send;
char send_data[1024], recv_data[4096];
struct hostent *host;
struct sockaddr_in server_addr;
host = gethostbyname("127.0.0.1");
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("SocketError");
exit(1);
}
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(50500);
server_addr.sin_addr = *((struct in_addr *) host->h_addr);
bzero(&(server_addr.sin_zero), 8);
if (connect(sock, (struct sockaddr *) &server_addr, sizeof(struct sockaddr))
== -1) {
perror("ConnectToError");
exit(1);
}
bytes_send = send(sock, a, strlen(a), 0);
bytes_send = shutdown(sock, 1);
bytes_recieved = recv(sock, recv_data, 4096, 0); //Where the program hangs??
recv_data[bytes_recieved] = 'void sockStuff() {
int sock, bytes_recieved,bytes_send;
char send_data[1024], recv_data[4096];
struct hostent *host;
struct sockaddr_in server_addr;
host = gethostbyname("127.0.0.1");
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("SocketError");
exit(1);
}
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(50500);
server_addr.sin_addr = *((struct in_addr *) host->h_addr);
bzero(&(server_addr.sin_zero), 8);
if (connect(sock, (struct sockaddr *) &server_addr, sizeof(struct sockaddr))
== -1) {
perror("ConnectToError");
exit(1);
}
bytes_send = send(sock, a, strlen(a), 0);
bytes_send = shutdown(sock, 1);
bytes_recieved = recv(sock, recv_data, 4096, 0); //Where the program hangs??
recv_data[bytes_recieved] = '\0';
printf("\nRecieved data = %s ", recv_data);
cout << endl << endl;
shutdown(sock,2);
}
';
printf("\nRecieved data = %s ", recv_data);
cout << endl << endl;
shutdown(sock,2);
}
Mon Client est en C/C++ et côté serveur est OpenEdge Progrès.
Veuillez voir le code et de suggérer ce qui s'est passé avec le présent.??
Vous devriez être en utilisant sizeof(server_addr.sin_zero) plutôt que le nombre magique 8. Ou mieux encore à zéro l'ensemble de la structure, puis de définir les champs qui vous intéressent.
Salut Neil, pouvez-vous préciser plus ce que j'ai essayé sizeof(server_addr.sin_zero), plutôt que le nombre de 8, mais toujours pas de chance.Thnx.
Salut Neil, pouvez-vous préciser plus ce que j'ai essayé sizeof(server_addr.sin_zero), plutôt que le nombre de 8, mais toujours pas de chance.Thnx.
OriginalL'auteur Vishal | 2009-12-11
Vous devez vous connecter pour publier un commentaire.
Votre code de bloc dans le recv appel jusqu'à ce que le serveur envoie des données en retour. Depuis ce n'est pas le cas, vous devriez peut-être demander vous-même si votre client a envoyé la demande complète. Le serveur ne sera probablement pas commencer l'envoi de la réponse jusqu'à ce que la demande complète est reçue.
Si votre protocole client/serveur est en mode texte, comme HTTP ou SMTP, êtes-vous sûr que votre réponse est correctement terminé? Le serveur attend peut-être CR+LF ('\r\n') au lieu de simplement LF ('\n') ou il s'attend à une ligne vide pour mettre fin à la demande:
PS. Vous ne déclarez pas ou initialiser 'a' dans votre extrait de code.
OriginalL'auteur notacat
Votre code de bloc dans le recv appel jusqu'à ce que le serveur envoie des données en retour. Depuis ce n'est pas le cas, vous devriez peut-être demander vous-même si votre client a envoyé la demande complète. Le serveur ne sera probablement pas commencer l'envoi de la réponse jusqu'à ce que la demande complète est reçue.
Si votre protocole client/serveur est en mode texte, comme HTTP ou SMTP, êtes-vous sûr que votre réponse est correctement terminé? Le serveur attend peut-être CR+LF ('\r\n') au lieu de simplement LF ('\n') ou il s'attend à une ligne vide pour mettre fin à la demande:
char *request = "GET /index.html HTTP/1.1\r\nHost: http://www.example.com\r\n\r\n"; PS. Vous ne déclarez pas ou initialiser 'a' dans votre extrait de code." par notacat
Je travaillais sur mon exemplaire, le début de winsock 1.0 et 1.1 mise en œuvre en c++ sur la victoire.
Mon code a travaillé tout le chemin à l'appel recv (), et puis il suffit de l'accrocher là... je savais à propos du blocage de \Non le blocage des sockets, mais ce n'était pas la solution que j'ai besoin. Depuis que j'ai vu ma demande, dans wireshark ou similaire, je savais que le serveur a été la réception de ma fin de chaîne de requête sur le port 80, et mon code de gel sur appel recv() en raison de la non communication entre mon client et serveur sur le net. Ce qui me fait croire que je n'ai pas soumettre de demande appropriée. ainsi, l'auteur ( notaket ) était sur place!. Dès que j'ai changé à sa demande( "GET /index.html HTTP/1.1\r\nHost: http://www.example.com\r\n\r\n") , tous semblent fonctionner comme un charme!. Merci!!
OriginalL'auteur blackshark
recv
devrait pendre jusqu'à u obtenir formulaire de réponse du serveur, vous avez déclaré que la réponse est en cours d'envoi.Essayez de wireshark ou quelque chose comme ça pour sniffer le réseau et voir si la réponse réelle est de venir ou pas.
OriginalL'auteur Arkaitz Jimenez
Ummm.... pourquoi avez-vous de l'arrêt de la prise....
Et pourtant, vous avez continué dans le code de recevoir de la même socket qui a été arrêté??
Espère que ce que des conseils dans la bonne direction,
Meilleures salutations,
Tom.
Ok...developerweb.net/forum/showthread.php?t=2940 - il y a une discussion intéressante abotu lors de l'utilisation de shutdown.. Le code en mode synchrone, il pourrait être possible que la réception de données qui s'est déjà produit avant l'arrêt et donc de l'accrocher. Avez-vous pensé à...? Désolé si je ne suis pas beaucoup d'une aide ici... 🙁
OriginalL'auteur t0mm13b
Recv bloquera jusqu'à ce que le socket a de l'information à lire aussi longtemps que le support est en mode de blocage, vous pouvez changer cela avec fcntl.
Si vous vous demandez pourquoi il est encore accroché, j'imagine que lorsque vous arrêtez l'écriture pipe sur le socket (aussi, vous pouvez utiliser la constante SHUT_WR que c'est mieux de style) le serveur reçoit un EOF et suppose que vous êtes à la déconnexion, mais qui pourrait ne pas être le cas si le serveur est configuré pour gérer.
Je suggère à la recherche à la mise sur le socket en mode sans blocage, puis de l'appel d' sélectionnez qui permet de bloquer jusqu'à ce que le support est accessible en lecture/écriture/ou un délai d'attente est déclenchée. En fonction de ce que vous faites, qui va faire une différence.
OriginalL'auteur Travis
Essayez d'utiliser le Non blocage de la mode. c'est à dire recv sera de retour si aucune donnée n'est là pour être lu, donc gérer ce cas (dans une boucle while ou avec choix. c'est à vous de voir)
Pour en savoir plus sur recv, en supposant que vous êtes sur un compatible POSIX système) lire ce
http://www.opengroup.org/onlinepubs/009695399/functions/recv.html
OriginalL'auteur ka05