2014-10-04 70 views
0

我一直在这里呆了一段时间,所以我真的希望有人能够为我提供一些关于发生什么的敏锐洞察力。当传递sockaddr_in作为参数时,connect()函数失败

我有以下主要功能:现在

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

int main(int argc, char **argv) { 

char *serv_IP; 
in_port_t serv_port; 
int sock; 
struct sockaddr_in serv_addr; 

serv_IP = argv[1]; 
serv_port = atoi(argv[2]); 

if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { 
    fprintf(stderr, "Failed to create TCP socket\r\n"); 
    exit(1); 
} 

memset(&serv_addr, 0, sizeof(serv_addr)); 
serv_addr.sin_family = AF_INET; 

if (inet_pton(AF_INET, serv_IP, &serv_addr.sin_addr.s_addr) == 0) { 
    fprintf(stderr, "Invalid IP address\r\n"); 
    exit(1); 
} 

serv_addr.sin_port = htons(serv_port); 

if (connect(sock, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) { 
    fprintf(stderr, "Failed to connect to serv\r\n"); 
    exit(1); 
} 
else { 
    printf("You're connected!\n); 
} 
close(sock) 
return 0; 
} 

,此代码的工作就好了。不过,我想要做的就是调用替换用一个辅助函数调用connect()以这样的事:

void function(int sock, struct sockaddr_in *serv_addr) { 

if (connect(sock, (struct sockaddr *) serv_addr, sizeof(serv_addr)) < 0) { 
    printf("Server IP = %s\n", inet_ntoa(serv_addr->sin_addr)); 
    printf("Server port = %d\n", ntohs(serv_addr->sin_port)); 
    fprintf(stderr, "Failed to connect to server\r\n"); 
    exit(1); 
} 
else { 
    // Do other stuff 
} 
} 

我从主删除呼叫接通()(),并用其替换函数调用:

function(sock, &serv_addr); 

只要函数被调用,就会打印出正确的IP和端口号,但我仍然无法连接到我的服务器。唯一的区别是,在我的主函数()中,我在与&的连接调用中前缀serv_addr - 即,连接(sock,(struct sockaddr *)& serv_addr,sizeof(serv_addr)) - 引用其地址,我不这样做,因为serv_addr的地址已经作为参数传递 - 即,connect(sock,(struct sockaddr *)serv_addr,sizeof(serv_addr))。如果我添加&,则不会产生任何影响,以防万一您想知道。

所以,用& serv_addr被传递给函数()看似正确,如我能打印出正确的IP和端口号验证,为什么我可以在主连接(),但不当我将serv_addr结构作为参数传递给另一个函数并从那里调用connect()时?

在此先感谢您的帮助!

回答

1

sizeof(serv_addr)返回16时,serv_addr宣布为sockaddr_in,但返回4(32位)或8(64位)当宣布为sockaddr_in*。这是太小,无论如何,AF_INET需要16.如果你看errnoconnect()失败,它会告诉你,你传递了一个无效的参数值。

您需要使用sizeof(sockaddr_in),无论是直接:

void function(int sock, struct sockaddr_in *serv_addr) 
{ 
    if (connect(sock, (struct sockaddr *) serv_addr, sizeof(sockaddr_in)) < 0) 

或间接地通过sizeof(*serv_addr)

void function(int sock, struct sockaddr_in *serv_addr) 
{ 
    if (connect(sock, (struct sockaddr *) serv_addr, sizeof(*serv_addr)) < 0) 
0

这做到了!非常感谢您的快速响应!我从来不会想到sizeof()的返回值是返回实际值与指向值的指针不同大小的潜在问题。尽管如此,完全合理。我刚刚阅读了errno.h头文件以及如何使用它。

是固定它的确切行:

if (connect(sock, (struct sockaddr *) serv_addr, sizeof(struct sockaddr_in)) < 0) 

我是对的不需要的“&”在serv_add面前。您还需要sizeof()中的“struct”,否则它将返回sockaddr_in作为未声明的变量。

无论如何,再次感谢。

现在我终于可以继续我的代码。