2010-11-22 17 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