Retourner aux forums || Retourner au forum Programmation.c

Programmation.c : Problem avec send()

Posté par cecile3147 () le 07 mars 2007
0
Je dois realiser un programme qui permettrait d'envoyer des messages d'un server a un client.
Apparement ma fonction send() renvoie toujours -1 je n'arrive pas a savoir pour quoi, si vous pouviez m'aider. Voici le code du coté client.



#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#define bufLength 1024

void makeLocalSocketAdress(struct sockaddr_in *sa){
sa->sin_family =AF_INET;
sa->sin_port=htons(0); // any port or port 2222 ????? htons(atoi(argv[1]))
sa->sin_addr.s_addr = htonl(INADDR_ANY); // on local host
}

void makeRemoteSocketAdress(struct sockaddr_in *sa, char * hostname, int port) {
struct hostent *host;

if ((host= gethostbyname(hostname))==NULL){
printf("Unknown host name \n");exit(-1);
}
sa->sin_family = AF_INET ;
sa->sin_addr= *(struct in_addr *)(host->h_addr); //memcpy((char*)&(sa->sin_addr.s_addr), host->h_addr,host->h_length);
sa->sin_port = htons(port);

}

int main(int argc, char *argv[]){

int sock,port;
struct sockaddr_in serverAdress;
struct sockaddr_in clientAdress;
int addrLength=sizeof(struct sockaddr_in);
char msg[bufLength]; //message to send/receive
char * hostname=malloc(30); // server adress

extern char *optarg;
extern int optind;
int semantic=0;
int c=0;

if (argc <3){
printf("Please provide server and port number \n");exit(-1);
}
while ((c = getopt(argc, argv, "lm")) != -1) {
switch (c) {
case 'l':
semantic = 0; //0 at-least-once semantic
break;
case 'm':
semantic = 1; //1 at-most-once semantic
break;
default: printf("usage: cmd [-l][-m][adress server][port number] \n");
}
}

strcpy(hostname,argv[argc-2]); // Copy the server adress given by the client in the variable hostname
port = atoi(argv[argc-1]); // Copy the port number given by the client in the variable port
port=htons(port);

if ((sock = socket(AF_INET,SOCK_DGRAM,0))== -1){ // creation socket for internet communication domain over UDP
printf("Error creation socket\n");exit(-1);
}
makeLocalSocketAdress(&clientAdress);
if((bind(sock,(struct sockaddr*)&clientAdress,addrLength))==-1){ // bind socket
printf("Error bind socket\n");exit(-1);
}

makeRemoteSocketAdress(&serverAdress,hostname,port);
strcpy(msg,"message envoye et bien recu");
printf("message : %s \n",msg);

if (sendto(sock,msg,strlen(msg),0,(struct sockaddr *)&serverAdress,addrLength) !=0 ) {
perror("Receive 1") ;
printf("Error send to\n");}
return 0;
}

> Lire le message (5 commentaires, moyenne: 1).  

Cette discussion est archivée, il n'est plus possible de laisser des commentaires.

Note : les commentaires appartiennent à ceux qui les ont postés. Nous n'en sommes pas responsables.

bind -> connect

Posté par kesako () le 07/03/2007 à 14:57. (lien). Évalué à 0.

Bind () c'est pour les serveur .

pour un client, il faut faire connect()

  • [^]Re: bind -> connect

    Posté par Vincent ORDY () le 07/03/2007 à 15:08. (lien). Évalué à 2.

    hum hum

    sock = socket(AF_INET,SOCK_DGRAM,0))== -1){
    // creation socket for internet communication domain over UDP

    //...

    if (sendto(sock,msg,strlen(msg),0,(struct sockaddr *)&serverAdress,addrLength) !=0 ) {


    C'est de l'UDP, pas du TCP !! Donc bind() pour le serveur ET le client, et jamais de connect().

    Voir les schémas de http://www.spi.ens.fr/beig/systeme/sockets.html par exemple

.

Posté par Vincent ORDY () le 07/03/2007 à 15:04. (lien). Évalué à 1.

Bonjour,

Il y a 2 petits problèmes :

- double htons()

port=htons(port);
// ...
makeRemoteSocketAdress(&serverAdress,hostname,port);
// -->
// ...
sa->sin_port = htons(port);

- sendto() renvoie la taille du message envoyé, donc il ne faut pas tester != 0 mais < 0 ou == -1 !

man sendto

Posté par Cereal Killer (Jabber id, ) le 07/03/2007 à 19:37. (lien). Évalué à 1.

J'ai pas pris le temps de tout lire/comprendre tout ton source mais pour moi, selon le man, sendto() renvoie le nombre de caractère si OK, sinon -1.

J'aurais plus fait un truc style :

if (sendto(sock,msg,strlen(msg),0,(struct sockaddr *)&serverAdress,addrLength) == -1)
{
perrror("Receive 1");
printf("error\n");
}

Re: Problem avec send()

Posté par l0stman () le 19/03/2007 à 16:58. (lien). Évalué à 1.

Salut,

Tout d'abord quelques remarques:

1 - Le client n'as besoin que de l'adresse du serveur pour envoyer le paquet donc il est inutile d'avoir clientAddress -- ton adresse le noyau s'en charge puisqu'il le connaît déjà.

2 - Pour la même raison que précedemment, bind() n'est pas obligatoire du côté client -- c'est superflu.

Enfin la raison pour laquelle ton code ne marche pas c'est que ton socket tu l'as rattachée à une addresse nulle:


makeLocalSocketAdress(&clientAdress);

if((bind(sock,(struct sockaddr*)&clientAdress,addrLength))==-1){ // bind socket

printf("Error bind socket\n");exit(-1);

}


Alors qu'après tu veux envoyer le paquet au serveur:

if (sendto(sock,msg,strlen(msg),0,(struct sockaddr *)&serverAdress,addrLength) !=0 ) {

perror("Receive 1") ;

printf("Error send to\n");}


Donc je pense que c'est normal que le paquet ne soit pas envoyé. Pour simplifier, voilà un code qui devrait marcher.


#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>

#include <netinet/in.h>
#include <netdb.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#define BUFSIZ 1024
#define HOST localhost /* à changer */
#define PORT 80

void
make_remote_socket_adress(struct sockaddr_in *sa, char * hostname, int port) {
struct hostent *host;

if ((host = gethostbyname(hostname)) == NULL) {
printf("Unknown host name.\n");
exit(-1);
}

memset(&sa, '0', sizeof(sa));
sa->sin_family = AF_INET ;
sa->sin_addr = memcpy(&sa.sin_addr, host->h_addr, host->h_length);
sa->sin_port = htons(port);
}

int
main(int argc, char *argv[]){

int sock,
int bytes_sent, msg_length;
struct sockaddr_in server_address;
char msg[BUFSIZ]; //message to send/receive

sprintf(msg, "Hello World!\n");
msg_length = strlen(msg) + 1;

if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) = -1) {
printf("Error creating socket.");
exit(-1);
}

make_remote_socket_address(server_address, HOST, PORT);

bytes_sent = sendto(sock, msg, msg_length, 0,(struct sockaddr*) &server_address, sizeof(struct sockaddr_in) );

if (bytes_sent < 0) {
perror("sendto");
exit(-1);
}

close(sock);
return 0;
}


Aprés, tu peux après rajouter les détails qui manquent et toussa (véritable addresse et port).

NB: je n'ai pas testé le code donc je ne sais pas s'il est correct mais le principe est là.

--
``Whatever it is, I'm against it'' -- Marx Groucho

Revenir en haut de page || Retourner aux forums || Retourner au forum Programmation.c