2013-01-23 52 views
1

这是我的问题:我正在写一个简单的客户端,它将连接到服务器使用服务器的主机名和端口号作为命令行参数。它编译得很好,但是当我运行客户端时,我从perror()收到一条消息,说“错误:地址族不受协议支持”。不知道为什么我得到这个错误,但我知道当我调用connect()时发生错误。出于某种原因,connect无法在我的sockaddr_in结构中找到地址族信息。任何帮助将非常感激。“协议不支持地址”当运行客户端

int main(int argc, char* argv[]) 
{ 
    if(argv[1] == NULL) 
    { 
     printf("if 1\n"); 
     perror("Error: argv[1]:hostname\n"); 
     exit(1); 
    } 

    struct sockaddr_in* servaddr = getServerInfo(argv[1], argv[2]); 
    int socketfd = createSocket(); 

    if(socketfd < 0) 
    { 
     printf("if 2\n"); 
     perror("Error: socketfd\n"); 
     exit(1); 
    } 

    int commResult = communicate(socketfd, servaddr); 

    if(commResult < 0) 
    { 
     printf("if 3\n"); 
     perror("Error: communication\n"); 
     exit(1); 
    } 

    return 0; 
} 

struct sockaddr_in* getServerInfo(char* hostname, char* port) 
{ 
    struct sockaddr_in* servaddr = malloc((size_t)sizeof(struct sockaddr_in)); 
    struct hostent *hostptr; 
    hostptr = gethostbyname(hostname); 

    memset((void *) servaddr, 0, (size_t)sizeof(*servaddr)); 
    servaddr->sin_family = (short)(AF_INET); 
    memcpy((void*)& servaddr->sin_addr, (void *) hostptr->h_addr, hostptr->h_length); 
    servaddr->sin_port = htons((u_short)atoi(port)); 

    return servaddr; 
} 


int createSocket() 
{ 
    int socketfd = socket(AF_INET, SOCK_STREAM, 0); 
    if(socketfd < 0) 
    { 
     return -1; 
    } 

    return socketfd; 
} 

int communicate(int socketfd, struct sockaddr_in* servaddr) 
{ 
    char buffer[BUFFERSIZE]; 

    // connect to the server at the location displayed by TCPserver.c 
    if(connect(socketfd, (struct sockaddr*)&servaddr, sizeof(*servaddr)) < 0) 
    { 
     printf("if 4\n"); 
     perror("ERROR: connecting to socket\n"); 
     return -1; 
    } 

    printf("Connected to server\n"); 

    strcpy(buffer, "This is the message I want the client to echo on the screen to prove that we can communicate together.\n"); 

    write(socketfd, buffer, strlen(buffer)+1); 

    return 0; 
} 

这里是服务器端的代码,以及:

int main() 
{ 
char * hostname = malloc(MAXSIZE * sizeof(char)); 
char buffer[BUFFERSIZE]; 

struct sockaddr_in* servaddr = getServerInfo(hostname); 
int listensockfd = createSocket(servaddr), connsockfd; 
printServerInfo(hostname, servaddr); 

listen(listensockfd, MAX_NUM_LISTENER_ALLOWED); 

connsockfd = accept(listensockfd, NULL, NULL); 
read(connsockfd, buffer, BUFFERSIZE); 
printf("Message: %s\n", buffer); 

// free memory 
free(servaddr); 
free(hostname); 

return 0; 
} // End main 

struct sockaddr_in* getServerInfo(char* hostname) 
{ 
    struct sockaddr_in* servaddr = malloc((size_t)sizeof(struct sockaddr_in)); 
    gethostname(hostname, 32); 
    struct hostent *hostptr; 
    hostptr = gethostbyname(hostname); 

     memset((void *) servaddr, 0, (size_t)sizeof(*servaddr)); 
     servaddr->sin_family = (short)(AF_INET); 
     memcpy((void *)& servaddr->sin_addr, (void *) hostptr->h_addr, hostptr->h_length); 
     servaddr->sin_port = htons((u_short)38000); 

    return servaddr; 
} 

int createSocket(struct sockaddr_in* servaddr) 
{ 
    int listensockfd = socket(AF_INET, SOCK_STREAM, 0); 

    bind(listensockfd, (struct sockaddr *) &servaddr, (socklen_t)sizeof(servaddr)); 

    socklen_t listensocklen = sizeof(servaddr); 
    getsockname(listensockfd, (struct sockaddr*)&servaddr, &listensocklen); 

    return listensockfd; 
} 

void printServerInfo(char* hostname, struct sockaddr_in* servaddr) 
{ 
    struct hostent *hostptr; 
    hostptr = gethostbyname(hostname); 

    printf("Host Name: %s\n", hostname); 
    printf("Host IP: %s\n", inet_ntoa(*(struct in_addr*)*hostptr->h_addr_list)); 
    printf("Port Number: %d\n", htons(servaddr->sin_port)); 
} 

回答

3

您在servaddr面前,这已经是一个指针有虚假&。实际上,您将指针在堆栈上的地址传递给connect(),而不是实际指向struct sockaddr_in的指针。

替换此:

if(connect(socketfd, (struct sockaddr*)&servaddr, sizeof(*servaddr)) < 0) 

与此:

if(connect(socketfd, (struct sockaddr*)servaddr, sizeof(*servaddr)) < 0) 

,它会工作。

在服务器中,bind()getsockname()createSocket()的调用中存在相同的错误。此外,在同一个函数的两个地方使用sizeof(servaddr)(这是指针的大小)而不是sizeof(*servaddr)

请注意,我强烈建议使用现代的getaddrinfo() API,而不要使用过时的gethostbyname()调用。

+0

感谢Daniel Roethlisberger的帮助。我不敢相信这是一个简单的错误。然而,我有一个新的错误。新错误显示“连接被拒绝”。我环顾了这个网站上的其他帖子,他们说,通常防火墙拒绝连接或端口关闭。许多人建议我在该主机名和端口号上运行telnet。当我这样做时说,连接被拒绝了。然而,我认为这个错误与我没有正确实现服务器或客户端有关。所以我发布了服务器代码。 – user1995624

+0

我不认为这是可能的另一个原因是因为我在属于同一网络的主机上运行客户端和服务器。也就是说,我的地方大学的网络。 – user1995624

+1

您在'createSocket()'中调用'bind()'和'getsockname()'时犯了完全相同的错误。您可以通过检查您的服务器是否使用'netstat'绑定到正确的地址/端口来检测到问题。 –

相关问题