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

nbnkbykc  于 2022-12-17  发布在  其他
关注(0)|答案(2)|浏览(263)

我已经在这一个不敬虔的时间量,所以我真的希望有人能给我一些敏锐的洞察力,到底是怎么回事。
我有以下主要职能:

#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和端口号就被打印出来了,但是我仍然无法连接到我的服务器。唯一的区别是,在我的主函数中(),我在connect调用中的serv_addr前面加上& -,即connect(套接字,(结构套接字地址 *)&服务器地址,大小(服务器_地址))-为了引用其地址,我不在helper函数中这样做,因为serv_addr的地址已经作为参数传递了,即connect(sock,(struct sockaddr *)serv_addr,sizeof(serv_addr)).如果我添加了&,也没有什么区别,只是以防万一您想知道。
那么,当&serv_addr被传递给function()时,看起来是 * 正确的,正如我能够打印出正确的IP和端口号所验证的那样,为什么我可以在main()中连接,而当我将serv_addr结构体作为参数传递给另一个函数并从那里调用connect()时却不能呢?
提前感谢您的帮助!

m2xkgtsf

m2xkgtsf1#

serv_addr声明为sockaddr_in时,sizeof(serv_addr)返回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(struct 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)
ccgok5k5

ccgok5k52#

成功了!非常感谢你的快速回应!!我从来没有想过sizeof()的返回会成为一个潜在的问题,因为它会为实际值和指向值的指针返回不同的大小。不过,这完全有意义。我刚刚读到了errno. h头文件以及如何使用它。
确切的台词是:

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

关于serv_add前面不需要'&',我是对的。您还需要sizeof()中的“struct”,否则它将sockaddr_in作为未声明的变量返回。
不管怎样,再次感谢。
现在我终于可以继续写代码了。

相关问题