2016-09-26 59 views
0

我建立一個多客戶UDP服務器C,但是當我試圖從一個系統連接到我的服務器,我得到這個錯誤對gethostbyaddr 錯誤:成功 請找到下面的服務器代碼。我試圖從類似的問題(gethostbyaddr() returns NULL but errno result in SUCCESS)的解決方案,但我不能讓它working.Any幫助將不勝感激錯誤的gethostbyaddr:成功

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

#define BUFSIZE 1024 

/* 
* error - wrapper for perror 
*/ 
void error(char *msg) { 
    perror(msg); 
    exit(1); 
} 

int main(int argc, char **argv) { 
    int sockfd; /* socket */ 
    int portno; /* port to listen on */ 
    int clientlen; /* byte size of client's address */ 
    struct sockaddr_in serveraddr; /* server's addr */ 
    struct sockaddr_in clientaddr; /* client addr */ 
    struct hostent *hostp; /* client host info */ 
    char buf[BUFSIZE]; /* message buf */ 
    char *hostaddrp; /* dotted decimal host addr string */ 
    int optval; /* flag value for setsockopt */ 
    int n; /* message byte size */ 
    FILE *fp; /* file variable */ 
    char str[10]; 
    int i = 0; 
    char userlist[10]; 
    int array_size; 
    char line[256]; 
    int cred,flag; 

    /* 
    * check command line arguments 
    */ 
    if (argc != 2) { 
    fprintf(stderr, "usage: %s <port>\n", argv[0]); 
    exit(1); 
    } 
    portno = atoi(argv[1]); 

    /* 
    * socket: create the parent socket 
    */ 
    sockfd = socket(AF_INET, SOCK_DGRAM, 0); 
    if (sockfd < 0) 
    error("ERROR opening socket"); 

    /* setsockopt: Handy debugging trick that lets 
    * us rerun the server immediately after we kill it; 
    * otherwise we have to wait about 20 secs. 
    * Eliminates "ERROR on binding: Address already in use" error. 
    */ 
    optval = 1; 
    setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, 
     (const void *)&optval , sizeof(int)); 

    /* 
    * build the server's Internet address 
    */ 
    bzero((char *) &serveraddr, sizeof(serveraddr)); 
    memset(&serveraddr,0,sizeof(serveraddr)); 
    serveraddr.sin_family = AF_INET; 
    serveraddr.sin_addr.s_addr = htonl(INADDR_ANY); 
    serveraddr.sin_port = htons((unsigned short)portno); 

    /* 
    * bind: associate the parent socket with a port 
    */ 
    if (bind(sockfd, (struct sockaddr *) &serveraddr, 
    sizeof(serveraddr)) < 0) 
    error("ERROR on binding"); 

    /* 
    * main loop: wait for a datagram, then echo it 
    */ 
    clientlen = sizeof(clientaddr); 
    while (1) { 

    /* 
    * recvfrom: receive a UDP datagram from a client 
    */ 
    bzero(buf, BUFSIZE); 
    n = recvfrom(sockfd, buf, BUFSIZE, 0, 
    (struct sockaddr *) &clientaddr, &clientlen); 
    if (n < 0) 
     error("ERROR in recvfrom"); 

    /* 
* gethostbyaddr: determine who sent the datagram 
*/ 
hostp = gethostbyaddr((const char *)&clientaddr.sin_addr.s_addr, 
      sizeof(clientaddr.sin_addr.s_addr), AF_INET); 
if (hostp == NULL) 
    error("ERROR on gethostbyaddr"); 
hostaddrp = inet_ntoa(clientaddr.sin_addr); 
if (hostaddrp == NULL) 
    error("ERROR on inet_ntoa\n"); 
printf("server received datagram from %s (%s)\n", 
    hostp->h_name, hostaddrp); 
printf("server received %d/%d bytes: %s\n", strlen(buf), n, buf); 

fp = fopen("users.txt", "r"); 
while (fgets(line, sizeof(line), fp)) { 
    //printf("%s\n",line); 
    cred = strncmp(buf,line,strlen(line)-1); 
    //printf("%d",strlen(line)-1); 
    if(cred == 0){ 
    printf("Authenticated...."); 
    flag = 1; 
    break; 
    } 
    else{ 
    printf("Invalid username/password"); 
    } 
} 
fclose(fp); 

回答

1

gethostbyaddr()需要一個指向一個struct in_addr作爲第一個參數,這將是&clientaddr.sin_addr爲你顯示的代碼。

表格相關(Linux)的文檔(man gethostbyaddr):

[...]主機地址參數是一個指向到根據地址類型的類型的結構,例如一個結構組in_addr *(可能通過致電inet_addr(3)獲得),用於地址類型AF_INET


gethostbyaddr()設置錯誤代碼h_errnoerrno

表相關(Linux)的文件(man gethostbyaddr):

返回值

[... [該的gethostbyname()gethostbyaddr()函數返回的hostent結構或空指針如果發生錯誤。出錯時,h_errno變量保存一個錯誤號。

可能的錯誤代碼被男人頁給出的還有:

錯誤

變量h_errno可以有以下值:

  • HOST_NOT_FOUND

    指定的主機未知。

  • NO_ADDRESS或NO_DATA

    請求的名稱是有效的,但沒有一個IP地址。

  • NO_RECOVERY

    發生不可恢復的名稱服務器錯誤。權威名稱服務器上出現

  • TRY_AGAIN

    暫時性錯誤。稍後再試。

+0

謝謝你的頭了,我試圖讓實際的錯誤,錯誤的是**錯誤上gethostbyaddr:未知主機**,但我想從每個系統來ping(包括本地和遠程)使用他們的IP,並沒有丟包,我不知道什麼是我的代碼錯誤,任何想法可能是這裏的問題? – Natto

+0

@Natto:請同時參閱我更新的答案的第一部分。 – alk

+0

我已經改變了第一個參數並嘗試了,但是我仍然得到相同的錯誤 – Natto