2010-11-22 63 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; 
} 

对不起,马虎的编码方式。我在这里得到错误。我如何调试它?Sendto()函数给出错误。如何调试它们?

的错误是这些

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

哇。那个缩进(或者它是否忽略它?)确实伤害了眼睛。 – sbi 2010-11-22 11:26:26

+0

除非您告诉我们确切的错误,否则我们可以帮助您。 – thkala 2010-11-22 11:32:14

+1

学会正确地缩进代码。很多问题都会得到解决。我在缩进代码的同时添加了一个右大括号。 – Aamir 2010-11-22 11:40:13

回答

1

首先更正代码:

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. 有没有需要动态分配的这样一个小的缓冲区,其大小在编译时是可预测的。
  2. s是一个string对象,而不是指向char*的指针。
  3. 即使它是指向char*的指针:由于源字符串可能包含格式代码('%'),因此非常不适合使用sprintf。想象一下,如果它包含'%s'会发生什么。
  4. 你怎么知道字符串不会超过19个字符?你在不能在编译时知道这一点。
  5. 无论如何,sprintf应该使用,如果你想做字符串格式。如果您只需要字符串,就不需要使用它。

这个耻辱名单可以继续。简单地说,你应该这样改写它:

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

关于你的具体问题。如果我们假设实际问题不是来自所提到的列表 - 通常会有互补的套接字函数,可以为您提供覆盖范围错误信息。

例如,在Windows上有一个WSAGetLastError函数,可以在出现错误后立即使用。

+0

OP使用标准的POSIX函数具有完美的便携性(即使是破碎的)代码。为什么在这里涉及特定于Windows的东西,当有更多的可移植替代品strerror(),perror()等? – thkala 2010-11-22 11:54:32

0

改变那些行:

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

第一个需要一个明确的转换,并在第二行,你必须明确地产生一个C风格的字符串来自C++字符串。

编辑:

记住的std :: string的c_str()方法仅提供一个指针的对象的内部结构。如果销毁字符串,该指针不再有效,所以请注意在必要时使用strdup()或类似命令。

EDIT2:

如果你真的想正确地做到这一点,你应该使用的strdup()代替的sprintf():

mess = strdup(s.c_str()); 

不要忘了free()函数的指针混乱当你完成它。

0

您的端口超出范围。对于TCP和UDP端口号是16位整数,即最高为65535

相关问题