[C] socket recv bloqué
Résolu
jaky1212
Messages postés
143
Statut
Membre
-
jaky1212 Messages postés 143 Statut Membre -
jaky1212 Messages postés 143 Statut Membre -
Bonjour,
Je programme un client en C sous windows seven. Mon problème est le suivant :
Je me connecte à google (avec la fonction connect(); ) puis j'envoie une requête (en respectant le protocole http/1.1 ) et suite a ce la je fais un recv(); pour récupérer ce que devrais m'envoyer google... Or mon programme se bloque a la fonction recv (); surement parce qu'elle ne reçoit rien ou n'envoie rien :s Pourtant la fonction connecte m'indique que je suis connecté au serveur ... Voici un petit bout de mon code :
SOCKET s;
s = socket(PF_INET, SOCK_STREAM, 0);
SOCKADDR_IN server;
server.sin_family = AF_INET;
server.sin_addr.s_addr = inet_addr("209.85.229.104");
server.sin_port = htons(80);
memset(&server.sin_zero, '\0', sizeof(server.sin_zero));
if (connect(s, (SOCKADDR *)&server, sizeof(server)) == SOCKET_ERROR)
fprintf(stderr, "La fonction connect a echoue.\n");
else
{
char *buffer;
buffer=(char*)calloc(500,sizeof(char));
int n;
printf("ooooo\n");
send(s, "GET / HTTP/1.1\r\nHost: www.google.fr\r\n", (int)strlen("GET / HTTP/1.1\r\nHost: www.google.fr\r\n"), 0);
printf("oooooo\n");
n = recv(s, buffer, sizeof(buffer), 0); /* Lire tout au plus sizeof(buffer) - 1 octets */
printf("oooo\n");
Résultat: seul les deux premiers "oooo" s'affiche, le troisième qui est après la fonction recv n'apparait pas :s
merci
Je programme un client en C sous windows seven. Mon problème est le suivant :
Je me connecte à google (avec la fonction connect(); ) puis j'envoie une requête (en respectant le protocole http/1.1 ) et suite a ce la je fais un recv(); pour récupérer ce que devrais m'envoyer google... Or mon programme se bloque a la fonction recv (); surement parce qu'elle ne reçoit rien ou n'envoie rien :s Pourtant la fonction connecte m'indique que je suis connecté au serveur ... Voici un petit bout de mon code :
SOCKET s;
s = socket(PF_INET, SOCK_STREAM, 0);
SOCKADDR_IN server;
server.sin_family = AF_INET;
server.sin_addr.s_addr = inet_addr("209.85.229.104");
server.sin_port = htons(80);
memset(&server.sin_zero, '\0', sizeof(server.sin_zero));
if (connect(s, (SOCKADDR *)&server, sizeof(server)) == SOCKET_ERROR)
fprintf(stderr, "La fonction connect a echoue.\n");
else
{
char *buffer;
buffer=(char*)calloc(500,sizeof(char));
int n;
printf("ooooo\n");
send(s, "GET / HTTP/1.1\r\nHost: www.google.fr\r\n", (int)strlen("GET / HTTP/1.1\r\nHost: www.google.fr\r\n"), 0);
printf("oooooo\n");
n = recv(s, buffer, sizeof(buffer), 0); /* Lire tout au plus sizeof(buffer) - 1 octets */
printf("oooo\n");
Résultat: seul les deux premiers "oooo" s'affiche, le troisième qui est après la fonction recv n'apparait pas :s
merci
A voir également:
- [C] socket recv bloqué
- Code puk bloqué - Guide
- Téléphone bloqué code verrouillage - Guide
- Pavé tactile bloqué - Guide
- Compte gmail bloqué - Guide
- Windows update bloqué - Guide
7 réponses
A y est j'ai trouvé l'astuce !!!
J'ai cherché sans relâche et j'ai trouvé ce qui n'allait pas.
C'est juste un problème de requête HTTP.
Il te manque un deuxième retour à la ligne pour fonctionner,
du coup, le serveur considérait ta requête comme incomplète
et ne daignait même pas répondre ce bougon.
Voilà monsieur !
De mon côté c'était encore plus vicieux car j'envoyais une bonne requête
mais avec en plus un caractère quelconque à la fin :
Comme quoi, il faut toujours vérifier les codes que l'on copie/colle sans réfléchir...
Voici la nouvelle version de mon code.
J'ai cherché sans relâche et j'ai trouvé ce qui n'allait pas.
C'est juste un problème de requête HTTP.
Il te manque un deuxième retour à la ligne pour fonctionner,
du coup, le serveur considérait ta requête comme incomplète
et ne daignait même pas répondre ce bougon.
"GET / HTTP/1.1\r\nHost: www.google.fr\r\n\r\n"
Voilà monsieur !
De mon côté c'était encore plus vicieux car j'envoyais une bonne requête
mais avec en plus un caractère quelconque à la fin :
send(s, req, len+1, 0);
Comme quoi, il faut toujours vérifier les codes que l'on copie/colle sans réfléchir...
Voici la nouvelle version de mon code.
#define VERBOSE
#include <winsock2.h>
#include <ws2tcpip.h>
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef VERBOSE
#define PRINT(c) printf(c)
#define WAIT_BEFORE_EXIT system("PAUSE")
#else
#define PRINT(c)
#define WAIT_BEFORE_EXIT
#endif
#define CLEANUP
#define ERROR_EXIT \
{ \
sprintf(s_out, "error %ld\n", WSAGetLastError()); \
PRINT(s_out); \
CLEANUP; \
WAIT_BEFORE_EXIT; \
return EXIT_FAILURE; \
} \
PRINT("OK\n");
static char host_name[] = "www.google.com";
char s_out[2048];
int main(int argc, char *argv[])
{
int result;
WSADATA w;
PRINT("WSAStartup: ");
result = WSAStartup(MAKEWORD(2, 2), &w);
if(result != 0) ERROR_EXIT;
if(LOBYTE(w.wVersion) != 2 || HIBYTE(w.wVersion) != 2)
{
PRINT("Could not find a usable version of Winsock.dll\n");
WSACleanup();
return(EXIT_FAILURE);
}
#undef CLEANUP
#define CLEANUP WSACleanup();
struct hostent *host;
struct in_addr addr;
PRINT("gethostbyname: ");
host = gethostbyname(host_name);
if(host == NULL) ERROR_EXIT;
PRINT("host_ip: ");
for(int i = 0; host->h_addr_list[i]; i++)
{
addr.s_addr = *(DWORD*) host->h_addr_list[i];
sprintf(s_out, "%s\t", inet_ntoa(addr)); PRINT(s_out);
}
PRINT("\n");
SOCKET s;
PRINT("socket: ");
s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(s == INVALID_SOCKET) ERROR_EXIT;
#undef CLEANUP
#define CLEANUP WSACleanup(); closesocket(s);
sockaddr_in clientService;
ZeroMemory(&clientService, sizeof(sockaddr_in));
clientService.sin_family = AF_INET;
clientService.sin_addr.s_addr = *(DWORD*) host->h_addr_list[0];
clientService.sin_port = htons(80);
PRINT("connect: ");
result = connect(s, (SOCKADDR*)&clientService, sizeof(clientService));
if(result == SOCKET_ERROR) ERROR_EXIT;
char req[1024], buffer[1024], lowbuffer[1024];
strcpy(req, "GET / HTTP/1.1\r\n");
strcat(req, "Host: "); strcat(req, host_name); strcat(req, "\r\n");
strcat(req, "\r\n");
size_t len = strlen(req);
sprintf(s_out, "REQ length : %d\nREQ msg :\n%s", len, req);
PRINT(s_out);
PRINT("send: ");
result = send(s, req, len, 0);
if(result < len) ERROR_EXIT;
do
{
PRINT("recv: ");
result = recv(s, buffer, 512, 0);
if(result < 0) ERROR_EXIT;
if(result)
{
buffer[result] = 0;
sprintf(s_out, "ANS length : %d\nANS msg :\n%s", result, buffer);
PRINT(s_out);
strcpy(lowbuffer, strupr(buffer));
}
} while(result == 512 && strstr(lowbuffer, "</html>") == NULL);
PRINT("shutdown_both: ");
result = shutdown(s, SD_BOTH);
if(result == SOCKET_ERROR) ERROR_EXIT;
PRINT("END\n");
CLEANUP;
WAIT_BEFORE_EXIT;
return EXIT_SUCCESS;
}
Bonjour,
Je suis désolé, je ne pense pas pouvoir répondre à ta question, à moins que ce ne soit une erreur de codage, je verrais demain.
Par contre, je voudrais savoir pourquoi tu mets : "buffer=(char*)calloc(500,sizeof(char)); " au lieu de éventuellement : "buffer = malloc(500 * sizeof(char))" ?
Par ailleurs, ca c'est pour toi, mais plutôt que de mettre des "oooo" met plutôt "La commande/fonction telle marche!" voire, et là ca te sera peut-être utile, le contenu des variables utilisées : "printf("Contenu de la variable tellevar : %d/%s", tellevar);" et un "system("PAUSE");" pour que tu ai le temps de suivre :).
Sur ce, bonne nuit et bon courage!
Je suis désolé, je ne pense pas pouvoir répondre à ta question, à moins que ce ne soit une erreur de codage, je verrais demain.
Par contre, je voudrais savoir pourquoi tu mets : "buffer=(char*)calloc(500,sizeof(char)); " au lieu de éventuellement : "buffer = malloc(500 * sizeof(char))" ?
Par ailleurs, ca c'est pour toi, mais plutôt que de mettre des "oooo" met plutôt "La commande/fonction telle marche!" voire, et là ca te sera peut-être utile, le contenu des variables utilisées : "printf("Contenu de la variable tellevar : %d/%s", tellevar);" et un "system("PAUSE");" pour que tu ai le temps de suivre :).
Sur ce, bonne nuit et bon courage!
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
Salut,
j'ai le même pb que toi,
voila mon code :
j'ai le même pb que toi,
voila mon code :
#define VERBOSE
#include <winsock2.h>
#include <ws2tcpip.h>
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef VERBOSE
#define PRINT(c) printf(c)
#define WAIT_BEFORE_EXIT system("PAUSE")
#else
#define PRINT(c)
#define WAIT_BEFORE_EXIT
#endif
#define CLEANUP
#define ERROR_EXIT \
{ \
sprintf(s_out, "error %ld\n", WSAGetLastError()); \
PRINT(s_out); \
CLEANUP; \
WAIT_BEFORE_EXIT; \
return EXIT_FAILURE; \
} \
PRINT("OK\n");
static char host_name[] = "www.google.fr";
char s_out[2048];
int main(int argc, char *argv[])
{
WSADATA wsaData;
PRINT("WSAStartup: ");
if(WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) ERROR_EXIT;
if(LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2)
{
PRINT("Could not find a usable version of Winsock.dll\n");
WSACleanup();
return(EXIT_FAILURE);
}
#undef CLEANUP
#define CLEANUP WSACleanup();
struct hostent *host;
struct in_addr addr;
PRINT("gethostbyname: ");
if((host = gethostbyname(host_name)) == NULL) ERROR_EXIT;
PRINT("host_ip: ");
for(int i = 0; host->h_addr_list[i]; i++)
{
addr.s_addr = *(DWORD*) host->h_addr_list[i];
sprintf(s_out, "%s\t", inet_ntoa(addr)); PRINT(s_out);
}
PRINT("\n");
SOCKET ConnectSocket;
PRINT("socket: ");
if((ConnectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP))
== INVALID_SOCKET) ERROR_EXIT;
#undef CLEANUP
#define CLEANUP WSACleanup(); closesocket(ConnectSocket);
sockaddr_in clientService;
ZeroMemory(&clientService, sizeof(sockaddr_in));
clientService.sin_family = AF_INET;
clientService.sin_addr.s_addr = *(DWORD*) host->h_addr_list[0];
clientService.sin_port = htons(80);
PRINT("connect: ");
if(connect(ConnectSocket, (SOCKADDR*)&clientService, sizeof(clientService))
== SOCKET_ERROR) ERROR_EXIT;
int result;
char req[1024];
strcpy(req, "GET / HTTP/1.1\r\n");
strcat(req, "Host: "); strcat(req, host_name); strcat(req, "\r\n");
//strcat(req, "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; fr-FR; rv:1.7.10) Gecko/20050717 Firefox/1.0.6\r\n");
//strcat(req, "Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5\r\n");
//strcat(req, "Accept-Language: fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3\r\n");
//strcat(req, "Accept-Encoding: gzip,deflate\r\n");
//strcat(req, "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n");
//strcat(req, "Keep-Alive: 300\r\n");
//strcat(req, "Connection: keep-alive\r\n");
strcat(req, "\r\n");
size_t len = strlen(req);
sprintf(s_out, "Request length : %d\nRequest message :\n%s", len, req);
PRINT(s_out);
PRINT("send: ");
if((result = send(ConnectSocket, req, len+1, 0)) < len) ERROR_EXIT;
//PRINT("shutdown_send: ");
//if(shutdown(ConnectSocket, SD_SEND) == SOCKET_ERROR) ERROR_EXIT;
char buffer[513];
PRINT("recv: ");
if((result = recv(ConnectSocket, buffer, 512, 0)) <= 0) ERROR_EXIT;
buffer[result] = 0;
sprintf(s_out, "Answer length : %d\nAnswer message :\n%s", result, buffer);
PRINT(s_out);
PRINT("shutdown_both: ");
if(shutdown(ConnectSocket, SD_BOTH) == SOCKET_ERROR) ERROR_EXIT;
PRINT("END\n");
CLEANUP;
WAIT_BEFORE_EXIT;
return EXIT_SUCCESS;
}