gpt4 book ai didi

c - getaddrinfo 似乎在 Windows 和 Ubuntu 之间返回不同的结果?

转载 作者:行者123 更新时间:2023-11-30 18:13:52 24 4
gpt4 key购买 nike

我有以下两组代码:

Windows

#undef UNICODE

#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>

// link with Ws2_32.lib
#pragma comment (lib, "Ws2_32.lib")

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

//-----------------------------------------
// Declare and initialize variables
WSADATA wsaData;
int iResult;
INT iRetval;

DWORD dwRetval;
argv[1] = "www.google.com";
argv[2] = "80";
int i = 1;

struct addrinfo *result = NULL;
struct addrinfo *ptr = NULL;
struct addrinfo hints;

struct sockaddr_in *sockaddr_ipv4;
// struct sockaddr_in6 *sockaddr_ipv6;
LPSOCKADDR sockaddr_ip;

char ipstringbuffer[46];
DWORD ipbufferlength = 46;

/*
// Validate the parameters
if (argc != 3) {
printf("usage: %s <hostname> <servicename>\n", argv[0]);
printf("getaddrinfo provides protocol-independent translation\n");
printf(" from an ANSI host name to an IP address\n");
printf("%s example usage\n", argv[0]);
printf(" %s www.contoso.com 0\n", argv[0]);
return 1;
}
*/

// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed: %d\n", iResult);
return 1;
}

//--------------------------------
// Setup the hints address info structure
// which is passed to the getaddrinfo() function
ZeroMemory( &hints, sizeof(hints) );
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
// hints.ai_protocol = IPPROTO_TCP;

printf("Calling getaddrinfo with following parameters:\n");
printf("\tnodename = %s\n", argv[1]);
printf("\tservname (or port) = %s\n\n", argv[2]);

//--------------------------------
// Call getaddrinfo(). If the call succeeds,
// the result variable will hold a linked list
// of addrinfo structures containing response
// information
dwRetval = getaddrinfo(argv[1], argv[2], &hints, &result);
if ( dwRetval != 0 ) {
printf("getaddrinfo failed with error: %d\n", dwRetval);
WSACleanup();
return 1;
}

printf("getaddrinfo returned success\n");

// Retrieve each address and print out the hex bytes
for(ptr=result; ptr != NULL ;ptr=ptr->ai_next) {

printf("getaddrinfo response %d\n", i++);
printf("\tFlags: 0x%x\n", ptr->ai_flags);
printf("\tFamily: ");
switch (ptr->ai_family) {
case AF_UNSPEC:
printf("Unspecified\n");
break;
case AF_INET:
printf("AF_INET (IPv4)\n");
sockaddr_ipv4 = (struct sockaddr_in *) ptr->ai_addr;
printf("\tIPv4 address %s\n",
inet_ntoa(sockaddr_ipv4->sin_addr) );
break;
case AF_INET6:
printf("AF_INET6 (IPv6)\n");
// the InetNtop function is available on Windows Vista and later
// sockaddr_ipv6 = (struct sockaddr_in6 *) ptr->ai_addr;
// printf("\tIPv6 address %s\n",
// InetNtop(AF_INET6, &sockaddr_ipv6->sin6_addr, ipstringbuffer, 46) );

// We use WSAAddressToString since it is supported on Windows XP and later
sockaddr_ip = (LPSOCKADDR) ptr->ai_addr;
// The buffer length is changed by each call to WSAAddresstoString
// So we need to set it for each iteration through the loop for safety
ipbufferlength = 46;
iRetval = WSAAddressToString(sockaddr_ip, (DWORD) ptr->ai_addrlen, NULL,
ipstringbuffer, &ipbufferlength );
if (iRetval)
printf("WSAAddressToString failed with %u\n", WSAGetLastError() );
else
printf("\tIPv6 address %s\n", ipstringbuffer);
break;
case AF_NETBIOS:
printf("AF_NETBIOS (NetBIOS)\n");
break;
default:
printf("Other %ld\n", ptr->ai_family);
break;
}
printf("\tSocket type: ");
switch (ptr->ai_socktype) {
case 0:
printf("Unspecified\n");
break;
case SOCK_STREAM:
printf("SOCK_STREAM (stream)\n");
break;
case SOCK_DGRAM:
printf("SOCK_DGRAM (datagram) \n");
break;
case SOCK_RAW:
printf("SOCK_RAW (raw) \n");
break;
case SOCK_RDM:
printf("SOCK_RDM (reliable message datagram)\n");
break;
case SOCK_SEQPACKET:
printf("SOCK_SEQPACKET (pseudo-stream packet)\n");
break;
default:
printf("Other %ld\n", ptr->ai_socktype);
break;
}
printf("\tProtocol: ");
switch (ptr->ai_protocol) {
case 0:
printf("Unspecified\n");
break;
case IPPROTO_TCP:
printf("IPPROTO_TCP (TCP)\n");
break;
case IPPROTO_UDP:
printf("IPPROTO_UDP (UDP) \n");
break;
default:
printf("Other %ld\n", ptr->ai_protocol);
break;
}
printf("\tLength of this sockaddr: %d\n", ptr->ai_addrlen);
printf("\tCanonical name: %s\n", ptr->ai_canonname);
}

freeaddrinfo(result);
WSACleanup();

return 0;
}

Ubuntu

/*
** listener.c -- a datagram sockets "server" demo
*/

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

#define MYPORT "4950" // the port users will be connecting to

#define MAXBUFLEN 100

// get sockaddr, IPv4 or IPv6:
void *get_in_addr(struct sockaddr *sa)
{
if (sa->sa_family == AF_INET) {
return &(((struct sockaddr_in*)sa)->sin_addr);
}

return &(((struct sockaddr_in6*)sa)->sin6_addr);
}

int main(void)
{
int sockfd;
struct addrinfo hints, *servinfo, *p;
int rv;
int numbytes;
struct sockaddr_storage their_addr;
char buf[MAXBUFLEN];
socklen_t addr_len;
char s[INET6_ADDRSTRLEN];

memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC; // set to AF_INET to force IPv4
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = AI_PASSIVE; // use my IP

if ((rv = getaddrinfo(NULL, MYPORT, &hints, &servinfo)) != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
return 1;
}

// loop through all the results and bind to the first we can
for(p = servinfo; p != NULL; p = p->ai_next) {
if ((sockfd = socket(p->ai_family, p->ai_socktype,
p->ai_protocol)) == -1) {
perror("listener: socket");
continue;
}

if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
close(sockfd);
perror("listener: bind");
continue;
}

break;
}

if (p == NULL) {
fprintf(stderr, "listener: failed to bind socket\n");
return 2;
}

freeaddrinfo(servinfo);

printf("listener: waiting to recvfrom...\n");

addr_len = sizeof their_addr;
if ((numbytes = recvfrom(sockfd, buf, MAXBUFLEN-1 , 0,
(struct sockaddr *)&their_addr, &addr_len)) == -1) {
perror("recvfrom");
exit(1);
}

printf("listener: got packet from %s\n",
inet_ntop(their_addr.ss_family,
get_in_addr((struct sockaddr *)&their_addr),
s, sizeof s));
printf("listener: packet is %d bytes long\n", numbytes);
buf[numbytes] = '\0';
printf("listener: packet contains \"%s\"\n", buf);

close(sockfd);

return 0;
}

当我尝试 www.google.com 时,我在 Windows 上没有返回 ipv6 套接字 - 这是为什么?

输出:(ubuntu)

caleb@ub1:~/Documents/dev/cs438/mp0/MP0$ ./a.out www.google.com
IP addresses for www.google.com:

IPv4: 74.125.228.115
IPv4: 74.125.228.116
IPv4: 74.125.228.112
IPv4: 74.125.228.113
IPv4: 74.125.228.114
IPv6: 2607:f8b0:4004:803::1010

输出:(获胜)

Calling getaddrinfo with following parameters:
nodename = www.google.com
servname (or port) = 80

getaddrinfo returned success
getaddrinfo response 1
Flags: 0x0
Family: AF_INET (IPv4)
IPv4 address 74.125.228.114
Socket type: SOCK_STREAM (stream)
Protocol: Unspecified
Length of this sockaddr: 16
Canonical name: (null)
getaddrinfo response 2
Flags: 0x0
Family: AF_INET (IPv4)
IPv4 address 74.125.228.115
Socket type: SOCK_STREAM (stream)
Protocol: Unspecified
Length of this sockaddr: 16
Canonical name: (null)
getaddrinfo response 3
Flags: 0x0
Family: AF_INET (IPv4)
IPv4 address 74.125.228.116
Socket type: SOCK_STREAM (stream)
Protocol: Unspecified
Length of this sockaddr: 16
Canonical name: (null)
getaddrinfo response 4
Flags: 0x0
Family: AF_INET (IPv4)
IPv4 address 74.125.228.112
Socket type: SOCK_STREAM (stream)
Protocol: Unspecified
Length of this sockaddr: 16
Canonical name: (null)
getaddrinfo response 5
Flags: 0x0
Family: AF_INET (IPv4)
IPv4 address 74.125.228.113
Socket type: SOCK_STREAM (stream)
Protocol: Unspecified
Length of this sockaddr: 16
Canonical name: (null)

最佳答案

getaddrinfo 实际上返回从名称服务器获取的结构。此行为取决于操作系统。

关于c - getaddrinfo 似乎在 Windows 和 Ubuntu 之间返回不同的结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21448267/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com