c - in_addr_t 变量作为连接参数
c - in_addr_t variable as paramether of connect
我有一个 in_addr_t
类型的变量,我想将 connect()
与给定的 ip 一起使用。因此,我需要一个 (struct sockaddr *)
变量作为 connect()
的参数。如何使用 in_addr_t
变量插入?
in_addr_t var; // Given variable, not actually declared here ofc
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in *srvraddr = malloc(sizeof(struct sockaddr_in));
memset((void *) srvraddr, 0, sizeof(struct sockaddr_in));
srvraddr->sin_family = AF_INET;
srvraddr->sin_port = htons(PORT_A); // Big - little endian arch compatibility
srvraddr->sin_addr.s_addr = var; // Somehow assign var here? <<<<<
connect(sockfd, (struct sockaddr *) srvraddr, sizeof(struct sockaddr_in));
无论我尝试做什么,总是联系 returns 我 -1
。
使用 perror
我得到以下错误:Connection refused
.
这是我使用 connect() 在端口 80 上连接到 "example.com" 的方法:
#include <stdio.h>
#include <netdb.h>
#include <unistd.h>
int main(void)
{
int sockfd;
if ((sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {
fprintf(stderr, "socket");
return 0;
}
char domain[] = "example.com";
struct hostent *he;
he = gethostbyname (domain);
if (!he)
{
switch (h_errno)
{
case HOST_NOT_FOUND:
fputs ("The host was not found.\n", stderr);
break;
case NO_ADDRESS:
fputs ("The name is valid but it has no address.\n", stderr);
break;
case NO_RECOVERY:
fputs ("A non-recoverable name server error occurred.\n", stderr);
break;
case TRY_AGAIN:
fputs ("The name server is temporarily unavailable.", stderr);
break;
}
return 1;
}
if (he->h_length < 4)
return 1;
struct sockaddr_in srvraddr;
srvraddr.sin_len = sizeof(srvraddr);
srvraddr.sin_family = AF_INET;
srvraddr.sin_port = htons(80);
srvraddr.sin_addr = * (struct in_addr *) he->h_addr_list[0];
if (connect(sockfd, (struct sockaddr*)&srvraddr, srvraddr.sin_len) == -1) {
fprintf(stderr,"connect() failed\n");
return 1;
}
// Use conection here...
close(sockfd);
return 0;
}
How to insert use the in_addr_t
variable instead?
您不能将 in_addr_t
与 connect()
一起使用,而不是 struct sockaddr_in
。 connect()
接受不同的地址结构类型,但不接受任意类型。 IPv4 地址的正确结构类型是您已经在使用的 struct sockaddr_in
。您需要将远程主机地址的适当表示形式存储到其中。
显然,您已经有一个 in_addr_t
,您断言它代表远程地址,但不确定如何使用它:
in_addr_t var; // Given variable, not actually declared here ofc
[...]
srvraddr->sin_addr.s_addr = var; // Somehow assign var here? <<<<<
然而,您所展示的正是 POSIX 期望您做的。 POSIX 要求 struct sockaddr_in
的 sin_addr
成员是一个至少具有 s_addr
类型 in_addr_t
成员的结构。假设您拥有的 in_addr_t
实际上是您要连接的机器地址的正确表示,将该值分配给地址结构的 sin_addr.s_addr
是正确的。原则上,该结构可以有更多成员,但实际上,想要互操作的实现不需要您设置任何其他成员。大多数人根本没有其他成员。
但是请注意,仅仅因为 connect()
通过指针接收地址结构并不意味着您需要使用动态分配。这样做会更惯用一些:
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in srvraddr = { 0 };
srvraddr.sin_family = AF_INET;
srvraddr.sin_port = htons(PORT_A);
srvraddr.sin_addr.s_addr = var;
connect(sockfd, (struct sockaddr *) &srvraddr, sizeof(srvraddr));
除其他外,这可以让您不必事后释放内存。
Whatever I try to do connect always returns me -1. Using perror I get the following error: Connection refused.
据我所知,您提供的代码没有问题。您可能首先要检查如何获取 in_addr_t
值,并验证您使用的端口号。另一方面,不要忽视问题出在远程主机的可能性:也许您尝试连接的端口没有打开(对您)。
我有一个 in_addr_t
类型的变量,我想将 connect()
与给定的 ip 一起使用。因此,我需要一个 (struct sockaddr *)
变量作为 connect()
的参数。如何使用 in_addr_t
变量插入?
in_addr_t var; // Given variable, not actually declared here ofc
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in *srvraddr = malloc(sizeof(struct sockaddr_in));
memset((void *) srvraddr, 0, sizeof(struct sockaddr_in));
srvraddr->sin_family = AF_INET;
srvraddr->sin_port = htons(PORT_A); // Big - little endian arch compatibility
srvraddr->sin_addr.s_addr = var; // Somehow assign var here? <<<<<
connect(sockfd, (struct sockaddr *) srvraddr, sizeof(struct sockaddr_in));
无论我尝试做什么,总是联系 returns 我 -1
。
使用 perror
我得到以下错误:Connection refused
.
这是我使用 connect() 在端口 80 上连接到 "example.com" 的方法:
#include <stdio.h>
#include <netdb.h>
#include <unistd.h>
int main(void)
{
int sockfd;
if ((sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {
fprintf(stderr, "socket");
return 0;
}
char domain[] = "example.com";
struct hostent *he;
he = gethostbyname (domain);
if (!he)
{
switch (h_errno)
{
case HOST_NOT_FOUND:
fputs ("The host was not found.\n", stderr);
break;
case NO_ADDRESS:
fputs ("The name is valid but it has no address.\n", stderr);
break;
case NO_RECOVERY:
fputs ("A non-recoverable name server error occurred.\n", stderr);
break;
case TRY_AGAIN:
fputs ("The name server is temporarily unavailable.", stderr);
break;
}
return 1;
}
if (he->h_length < 4)
return 1;
struct sockaddr_in srvraddr;
srvraddr.sin_len = sizeof(srvraddr);
srvraddr.sin_family = AF_INET;
srvraddr.sin_port = htons(80);
srvraddr.sin_addr = * (struct in_addr *) he->h_addr_list[0];
if (connect(sockfd, (struct sockaddr*)&srvraddr, srvraddr.sin_len) == -1) {
fprintf(stderr,"connect() failed\n");
return 1;
}
// Use conection here...
close(sockfd);
return 0;
}
How to insert use the
in_addr_t
variable instead?
您不能将 in_addr_t
与 connect()
一起使用,而不是 struct sockaddr_in
。 connect()
接受不同的地址结构类型,但不接受任意类型。 IPv4 地址的正确结构类型是您已经在使用的 struct sockaddr_in
。您需要将远程主机地址的适当表示形式存储到其中。
显然,您已经有一个 in_addr_t
,您断言它代表远程地址,但不确定如何使用它:
in_addr_t var; // Given variable, not actually declared here ofc
[...]
srvraddr->sin_addr.s_addr = var; // Somehow assign var here? <<<<<
然而,您所展示的正是 POSIX 期望您做的。 POSIX 要求 struct sockaddr_in
的 sin_addr
成员是一个至少具有 s_addr
类型 in_addr_t
成员的结构。假设您拥有的 in_addr_t
实际上是您要连接的机器地址的正确表示,将该值分配给地址结构的 sin_addr.s_addr
是正确的。原则上,该结构可以有更多成员,但实际上,想要互操作的实现不需要您设置任何其他成员。大多数人根本没有其他成员。
但是请注意,仅仅因为 connect()
通过指针接收地址结构并不意味着您需要使用动态分配。这样做会更惯用一些:
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in srvraddr = { 0 };
srvraddr.sin_family = AF_INET;
srvraddr.sin_port = htons(PORT_A);
srvraddr.sin_addr.s_addr = var;
connect(sockfd, (struct sockaddr *) &srvraddr, sizeof(srvraddr));
除其他外,这可以让您不必事后释放内存。
Whatever I try to do connect always returns me -1. Using perror I get the following error: Connection refused.
据我所知,您提供的代码没有问题。您可能首先要检查如何获取 in_addr_t
值,并验证您使用的端口号。另一方面,不要忽视问题出在远程主机的可能性:也许您尝试连接的端口没有打开(对您)。