Problème de Socket(recv)

Signaler
Messages postés
22
Date d'inscription
vendredi 14 mars 2003
Statut
Membre
Dernière intervention
9 juillet 2006
-
Messages postés
12
Date d'inscription
jeudi 19 novembre 2009
Statut
Membre
Dernière intervention
1 décembre 2010
-
Voila je suis en train d'essayer de faire un client FTp mais j'ai vraiment du mal...mon preblème c ke j'arrive pas à réceptionner les réponses du serveur donc je c po ou j'en suis du tout...je vous post les grande ligne du programme....

Je vous passe les Includes...la compilation est bonne...

char *ipaddr;
int port;
char *buffer;

int main(int argc, char *argv[])
{
if (argc != 3)
{
printf("\nUtilisation : .exe [Host] [port]\n");
getchar();
return 0;
}

WSADATA WSAData;
WSAStartup(MAKEWORD(2,0), &WSAData);

SOCKET sock;
SOCKADDR_IN sin;

sin.sin_addr.s_addr = inet_addr(ipaddr);
sin.sin_family = AF_INET;
sin.sin_port = htons(port);
sock = socket(AF_INET,SOCK_STREAM,0);
bind(sock, (SOCKADDR *)&sin, sizeof(sin));

connect(sock, (SOCKADDR *)&sin, sizeof(sin));
printf("\nConnection au FTP");

/* Sending USER */
send(sock, "USER Anonymous\r\n",16,0);

recv(sock, buffer, sizeof(buffer), 0);

printf("\nBuffer : %s",buffer);
printf("\nSizeOfBuffer : %d",sizeof(buffer));
getchar();

closesocket(sock);
WSACleanup();
getchar();
return 0;
}

Et donc le programme m'affiche que buffer fait une taille de 4 et qu'il a pour valeur "<NULL>"
Bien sur l'adresse du ftp que g mise est bonne vu ke je l'ai testé avec un logiciel FTP...c vraiment bizare...donc si vous avez des conseils, des idées...Je prends tout !!! Meme les critiques de code du moment que ca me fasse progresser....Par pitier j'aimerais comprendre

Thx d'avance et encore bravo pour votre site....il est vraiment kool

9 réponses

Messages postés
787
Date d'inscription
samedi 8 juin 2002
Statut
Membre
Dernière intervention
7 juin 2007
1
char *buffer;

Tu dois associer de la mémoire à ton buffer...

exemple : char* buffer = malloc(100*sizeof(char));
ou char buffer[100];

Et indiquer 100 au lieu de sizeof(buffer) dans recv(). Renseigne toi sur les pointeurs et les allocations mémoire, tu en auras besoin ;-)
Messages postés
22
Date d'inscription
vendredi 14 mars 2003
Statut
Membre
Dernière intervention
9 juillet 2006

Ba en fait o début j'avais mi un buffer[4096] mais bon j'avais changé parce ke y'avé des tutos ou il utilisaient un pointeur...Sinon imaginons que je mettes buffer[256] et que le server m'envoie ( enfin si un jour j'arrive a recevoir ce que le server me renvoie... ) et que la réponse fait plus de 256 ca ferait koi ?? Sinon si j'utilise sizeof ca fait quoi en plus ou moins ??
Messages postés
787
Date d'inscription
samedi 8 juin 2002
Statut
Membre
Dernière intervention
7 juin 2007
1
C'est à toi de gérer ce genre de cas... En général, on traite les données du buffer, puis on déplace les données non traitées au début du buffer, avant de lire la suite des données en le copiant à la suite du buffer (c'est dans ce cas qu'un pointeur est utile).

sizeof retourne la taille de la variable, pas de son contenu. En général (entiers, structures) c'est la même, mais pas pour les pointeurs, qui sont codés sur 32 bits soit 4 octets, et qui peuvent pointer sur n'importe quoi...
Messages postés
1536
Date d'inscription
samedi 21 décembre 2002
Statut
Membre
Dernière intervention
24 mai 2009
2
pour recupérer la taille des données ki peuvent etre recus, il faut utiliser getsockopt(), si jme souviens bien, ca fait 8ko.
Messages postés
402
Date d'inscription
mardi 1 mai 2001
Statut
Membre
Dernière intervention
15 août 2011

ioctlsocket() peut être utilisé aussi ...

int ret = 0;
unsigned long nbBytes = 0L;

if ( ! !ioctlsocket( sck, FIONREAD, &nbBytes ) ) {
puts("ioctlsocket() error: %d\n", WSAGetLastError());
return 0;
}

if ( nbBytes > 0L ) {

printf( "%lu octets presents\n", nbBytes );

/* 0(déconnecté), -1(erreur), >0(données recus) */
if ( (ret = recv( sck, buffer, nbBytes, 0 )) > 0 ) {

buffer[ret] = '\0';
printf("recu: %s\n", buffer);

}
else puts("recv() error: %d\n", WSAGetLastError());

}
else puts("pas de donnees\n");

Oui, par `Défaut` c'est 8ko/call à recv()

La taille d'un pointeur est variable. Identique au int, selon le système; 16, 32, 64, ... bits.

Comment fais-tu pour savoir que c'est ton recv() qui ne fonctionne pas ? Tu ne sais même pas si tu est réellement connecté au serveur FTP et si ta demande de connexion à été acceptée.

La validation, l'une des choses les plus imoprtante en programmation.

~(.:: NitRic ::.)~
Messages postés
22
Date d'inscription
vendredi 14 mars 2003
Statut
Membre
Dernière intervention
9 juillet 2006

Kool merci les gars, et surtout NitRic...J'essaye tout ca des que g du temps et je vous tiens o courant...thx encore
Messages postés
22
Date d'inscription
vendredi 14 mars 2003
Statut
Membre
Dernière intervention
9 juillet 2006

C Bon je viens de tout reprendre à zéro et ca marche...enfin ca se connecte et je recv la réponse du serveur...C deja ca me direz vous ^^ Sinon j'ai une autre petite question, je développe sous borland et j'aimerais remettre à zéro avant chaque recv mon buffer, pour ca aparement y'a bzero() qui appartient à strings.h ( bien avec le s ) mais kan je mets mon include, lors de la compilation impossible de linker la fonction bzero....quel autre moyen j'ai pour mettre à zéro mon buffer ?Thx a lot
Messages postés
402
Date d'inscription
mardi 1 mai 2001
Statut
Membre
Dernière intervention
15 août 2011

#include <string.h>

memset( buffer, 0, buffer_size );
strnset( buffer, 0, buffer_size );
...
...
...

Sinon, à la mano:

void __cdecl fill_buffer( char * buf, int c, size_t sz ) {
char * b = buf;
if ( sz && buf ) {
while ( sz-- ) *b++ = c;
}
}

fill_buffer( buffer, 0, buffer_size );

Prend la meilleur méthode et utilise la ! Perso je préfère le memset() aux autres ...

~(.:: NitRic ::.)~
Messages postés
12
Date d'inscription
jeudi 19 novembre 2009
Statut
Membre
Dernière intervention
1 décembre 2010

nice
Bonjour tr le monde ,

en faite je suis entrain de programmer une ptite application multithread qui envoie des sockets à des @ IP(10 @ en simultané) et selon le retour de select de socket il decode l'entete(IpHeader) et revoi le resultat ; si on teste la select avec un seul poste en simultané il marche trés biens alors que lorsque je tente de le testé avec plus que de 2 en simultanés la select retourne toujours 1 = sig que la select contient des donnees alors ce n est pas le cas ! (car ces adresses IP ne sont pas connectés ) !
voila un extrait de code :

// Initialisation du nombre de ping à faire = nombre de retrait
if(iNBPing == 0)
iNBPing = NBPINGDEFAULT;//si le nombre de retarit est a 0 on prend le nombre par default 1.

// Initialisation du délai d'attente
if(iTpsLimite == 0)
iTpsLimite = DEFALUTTIMEOUT;//si le delai d'attente est 0 on prend le timeout par defaut 1000 MS

while((CHote->iNbRetryUsed != iNBPing)&&(!bRstConn))
{
memset(szICMP_data,0,DATASIZE_ICMP);
iID = (unsigned short)GetCurrentProcessId() + CHote->iNbRetryUsed;
// Construction du paquet ICMP
IcmpHeader *icmp_hdr;
icmp_hdr = (IcmpHeader*)szICMP_data;
icmp_hdr->type = TYPE_ICMP_ECHO; // Type du paquet ICMP : echo request
icmp_hdr->code = CODE_ICMP_NULL; // Il n'y a pas de code spécifique pour ce type de paquet
icmp_hdr->id = iID;//identificateur de paquet
icmp_hdr->sequence = SEQU_ICMP_ECHO;
icmp_hdr->timestamp = GetTickCount(); // Initialisation du temps lors de l'envoi

// Somme de contrôle sur 16 bits
((IcmpHeader*)szICMP_data)->checksum = checksum((unsigned short*)szICMP_data, DATASIZE_ICMP);

// On envoie le paquet ICMP que l'on a construit
iEnvoi = sendto(sock, szICMP_data, DATASIZE_ICMP, 0, (struct sockaddr *)&sin, DATASIZE_ICMP);
FD_ZERO(&fdsr);
FD_SET(sock, &fdsr);

tv_timeout.tv_sec = iTpsLimite/1000;
tv_timeout.tv_usec = 0;


iFindelai = 0;

do{
if (select(sock+1, &fdsr, NULL, NULL, &tv_timeout) <= 0)
{
// Dans le cas où le temps est écoulé, on veut sortir de la boucle
// on compte le paquet comme envoyé mais perdu
// delai d'attente de la demande depassée
CHote->iNbRetryUsed = CHote->iNbRetryUsed+1;
iPerte= iPerte+1;
iFindelai = 1;

}

//Cette fonction vérifie si le descripteur "sock" est contenu dans l'ensemble "fdsr" après l'appel à select.
if (FD_ISSET(sock, &fdsr))
{
// Dans le cas où le buffer du socket contient des données,
// on les décode
iRecept=recvfrom(sock, szRecvbuf, MAX_PACKET, 0, (struct sockaddr *)&from, &iFromlen);

/***********************************************************/
iphdr = (IpHeader *)szRecvbuf;
iphdrlen = iphdr->h_len * 4 ;
icmphdr = (IcmpHeader*)(szRecvbuf + iphdrlen);

if(iID!=(icmphdr->id))
{
// Cas où le paquet n'est pas à nous
iFindelai= 0;
}
else
{
CHote->iNbRetryUsed = CHote->iNbRetryUsed +1;
iFindelai= 1;
}

/***************************************************/

memset(szRecvbuf,0,MAX_PACKET);
//dés la prmiere ping : si on a l'envoi est supérieur de perte on sort
if((CHote->iNbRetryUsed-iPerte)>0)
bRstConn=true;

}
}
while(iFindelai == 0);