2010-11-22 4 views
0
/* 
** talker.c -- a datagram "client" demo 
*/ 

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <errno.h> 
#include <string.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <arpa/inet.h> 
#include <netdb.h> 
#include <fstream> 
#include <iostream> 
#include <string> 


using namespace std ; 
#define SERVERPORT "3200775" // the port users will be connecting to 

int main() 
{ string s; 

ifstream f1 ("queries1.txt"); 
if (f1.is_open()) 

{ 
while (!f1.eof()) 
{ 
getline(f1,s); 
cout<<s<<endl; 
     } 

} 
    int sockfd; 
    //char ch [] = "hello"; 

struct addrinfo hints, *servinfo, *p; 
int rv; 
int numbytes; 

// if (argc != 3) { 
// fprintf(stderr,"usage: talker hostname message\n"); 
// exit(1); 
//} 

memset(&hints, 0, sizeof hints); 
hints.ai_family = AF_UNSPEC; 
hints.ai_socktype = SOCK_DGRAM; 

if ((rv = getaddrinfo("nunki.usc.edu", SERVERPORT, &hints, &servinfo)) != 0) { 
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv)); 
return 1; 
} 

// loop through all the results and make a socket 
for(p = servinfo; p != NULL; p = p->ai_next) 
{ 
if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) 
{ 
perror("talker: socket"); 
continue; 
} 

break; 
} 

if (p == NULL) 
{ 
fprintf(stderr, "talker: failed to bind socket\n"); 
return 2; 
} 

//if ((numbytes = sendto(sockfd,ch, strlen(ch), 0, 
// p->ai_addr, p->ai_addrlen)) == -1) { 
//perror("talker: sendto"); 
//exit(1); 

//for (f=0 ;f<15; f++) 
// { 

    char* mess = malloc(20*sizeof(char)); 
    sprintf(mess,s); 
     if ((numbytes = sendto(sockfd,mess, s.length(), 0, p->ai_addr, p->ai_addrlen)) == -1) 
{ cout<<s; 
    perror("talker: sendto"); 
    exit(1); 

} 
printf("talker: sent %d bytes to \n", numbytes); 
cout<<endl; 
//} 

freeaddrinfo(servinfo); 

//printf("talker: sent %d bytes to \n", numbytes); 

close(sockfd); 
return 0; 
} 

Désolé pour le mode de codage bâclé. Je reçois des erreurs dans ceci. Comment puis-je le déboguer?Fonction Sendto() donnant des erreurs. Comment les déboguer?

Les erreurs sont ces

test.cpp:84: error: invalid conversion from ‘void*’ to ‘char*’ 
test.cpp:85: error: cannot convert ‘std::string’ to ‘const char*’ for argument ‘2’ to ‘int sprintf(char*, const char*, ...)’ 
+1

Whoa. Cette indentation (ou est-ce la négligence?) Fait vraiment mal à l'œil. – sbi

+0

À moins que vous nous disiez exactement quelles erreurs vous obtenez, il est douteux que nous puissions vous aider. – thkala

+1

Apprenez à mettre le code correctement en retrait. Beaucoup de problèmes seront résolus. J'ai ajouté une accolade de fermeture tout en indentant votre code. – Aamir

Répondre

1

corrections First à votre code:

char* mess = malloc(20*sizeof(char)); 
sprintf(mess,s); 
if ((numbytes = sendto(sockfd,mess, s.length(), 0, p->ai_addr, p->ai_addrlen)) == -1) 
    // ... 
  1. Il n'y a pas besoin de alloué dynamiquement un petit tampon, dont la taille est prévisible à la compilation.
  2. s est un objet string, pas un pointeur vers char*.
  3. Même s'il s'agissait d'un pointeur sur char*: il est très impropre d'utiliser sprintf, car la chaîne source peut contenir des codes de format ('%'). Imaginez ce qui se passe s'il contient '% s'.
  4. Comment savez-vous que la chaîne ne dépassera pas 19 caractères? Vous ne pouvez pas savoir au moment de la compilation.
  5. Quoi qu'il en soit, sprintf devrait être utilisé si vous voulez faire le formatage de chaîne. Il n'y a pas besoin de l'utiliser si vous avez juste besoin de la chaîne telle quelle.

Cette liste de honte peut être continuée. En termes simples, vous devez le réécrire de la façon suivante:

if ((numbytes = sendto(sockfd, (char*) s.c_str(), s.length(), 0, p->ai_addr, p->ai_addrlen)) == -1) 
    // ... 

En ce qui concerne votre problème spécifique. Si nous supposons que le problème réel ne provient pas de la liste mentionnée, il existe généralement des fonctions de sockets complémentaires qui peuvent vous donner les informations d'erreur de portée. Par exemple, sous Windows, il existe une fonction WSAGetLastError qui peut être utilisée immédiatement après l'apparition de l'erreur.

+0

L'OP a un code parfaitement portable (même cassé), en utilisant les fonctions POSIX standard. Pourquoi impliquer quelque chose de spécifique à Windows ici, quand il y a les alternatives beaucoup plus portables de strerror(), perror() etc? – thkala

0

Modifier ces lignes à:

char *mess = (char *)malloc (20 * sizeof (char)); 
sprintf(mess, s.c_str()); 

Le premier a besoin d'un casting explicite, et dans la deuxième ligne vous devez produire explicitement une chaîne de style C à partir d'une chaîne C++.

EDIT:

Gardez à l'esprit que la méthode c_str() de std :: string fournit uniquement un pointeur vers une structure interne de l'objet. Si vous détruisez la chaîne, ce pointeur n'est plus valide, prenez donc soin d'utiliser strdup() ou similaire si nécessaire.

EDIT2:

Si vous voulez vraiment le faire correctement, vous devriez vraiment utiliser strdup() au lieu de sprintf():

mess = strdup(s.c_str()); 

Ne pas oublier de libérer() le pointeur mess quand vous en avez fini avec ça.

0

Votre port est hors de portée. Les numéros de port pour TCP et UDP sont des entiers de 16 bits, soit le maximum est 65535.

Questions connexes