Sendto()函数给出错误。如何调试它们?

时间:2010-11-22 11:22:25

标签: c++

    /*
** 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;
}

对于草率的编码方式感到抱歉。我在这里遇到错误。我该如何调试呢?

错误就是这些

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*, ...)’

3 个答案:

答案 0 :(得分: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. sstring个对象,而不是指向char*的指针。
  3. 即使它是指向char*的指针:它也非常不适合使用sprintf,因为源字符串可能包含格式代码('%')。想象一下如果它包含'%s'会发生什么。
  4. 你怎么知道字符串不会超过19个字符?你不能在编译时知道这一点。
  5. 无论如何,如果你想进行字符串格式化,应该使用sprintf。如果您只是需要字符串,则无需使用它。
  6. 这个耻辱名单可以继续。简单地说,你应该这样重写:

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

    关于您的具体问题。如果我们假设实际问题不是来自提到的列表 - 通常有补充套接字函数可以为您提供到达错误信息。

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

答案 1 :(得分: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());

当你完成它时,不要忘记释放()乱七八糟的指针。

答案 2 :(得分:0)

您的端口超出了范围。 TCP和UDP的端口号是16位整数,即最大值为65535。