首页 文章

传递sockaddr_in作为参数时,connect()函数失败

提问于
浏览
0

我已经花了不少时间,所以我真的希望有人可以为我提供一些有关正在发生的事情的敏锐见解 .

我有以下主要功能:

#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;
}

现在,这段代码工作得很好 . 但是,我想要做的是用一个helper函数调用替换对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
}
}

我从main()中删除对connect()的调用,并将其替换为函数调用:

function(sock, &serv_addr);

一旦调用该函数,就会打印出正确的IP和端口号,但我仍然无法连接到我的服务器 . 唯一的区别是,在我的main函数()中,我在连接调用中使用&前缀serv_addr - 即connect(sock,(struct sockaddr *) &serv_addr ,sizeof(serv_addr)) - 引用它的地址,我不要在辅助函数中执行此操作,因为serv_addr的地址已作为参数传递 - 即connect(sock,(struct sockaddr *) serv_addr ,sizeof(serv_addr)) . 如果我添加&,则没有区别,以防万一你想知道 .

因此,将&serv_addr传递给function()看似正确,正如我能够打印出正确的IP和端口号验证的那样,为什么我可以在main()中连接但是当我将serv_addr结构传递为另一个函数的参数并从那里调用connect()?

在此先感谢您的帮助!

2 回答

  • 0

    sizeof(serv_addr)serv_addr 被声明为 sockaddr_in 时返回16,但在声明为 sockaddr_in* 时返回4(在32位)或8(在64位) . 无论哪种方式都太小了, AF_INET 需要16.如果 connect() 失败了,你会看到 errno ,它会告诉你你传递了一个无效的参数值 .

    您需要直接使用 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)
    
  • 1

    那就做到了!非常感谢您的快速回复!!我永远不会想到sizeof()的返回是一个潜在的问题,它返回实际值的不同大小与指向值的指针 . 但是,完全有道理 . 我刚刚阅读了有关errno.h标头以及如何使用它的信息 .

    修复它的确切行是:

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

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

    无论如何,再次感谢 .

    现在我终于可以继续使用我的代码了 .

相关问题