linux c TCP/IP 编译getaddrinfo.c时出现error: storage size of ‘addrCriteria’ isn’t known解决办法。
原因是:netdb.h不是C99标准里定义的函数,是posix标准里的,-std=c99 会导致netdb.h无效了,但是-std=c99 才支持 for()指针语法,使用c99的话,经测试其他的getaddrinfo等函数就会出问题,故不使用-std=c99,换成while循环,问题解决。
请看源码:
1、getaddrinfo.c
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <netdb.h> #include "DieWithMessage.h" void PrintSocketAddress(const struct sockaddr *address, FILE *stream) { // Test for address and stream if (address == NULL || stream == NULL) return; void *numericAddress; // Pointer to binary address // Buffer to contain result (IPv6 sufficient to hold IPv4) char addrBuffer[INET6_ADDRSTRLEN]; in_port_t port; // Port to print // Set pointer to address based on address family switch (address->sa_family) { case AF_INET: numericAddress = &((struct sockaddr_in *) address)->sin_addr; port = ntohs(((struct sockaddr_in *) address)->sin_port); break; case AF_INET6: numericAddress = &((struct sockaddr_in6 *) address)->sin6_addr; port = ntohs(((struct sockaddr_in6 *) address)->sin6_port); break; default: fputs("[unknown type]", stream); // Unhandled type return; } // Convert binary to printable address if (inet_ntop(address->sa_family, numericAddress, addrBuffer, sizeof (addrBuffer)) == NULL) fputs("[invalid address]", stream); // Unable to convert else { fprintf(stream, "%s", addrBuffer); if (port != 0) // Zero not valid in any socket addr fprintf(stream, "-%u", port); } } int main(int argc, char *argv[]) { if (argc != 3) // Test for correct number of arguments DieWithUserMessage("Parameter(s)", "<Address/Name> <Port/Service>"); char *addrString = argv[1]; // Server address/name char *portString = argv[2]; // Server port/service // Tell the system what kind(s) of address info we want struct addrinfo addrCriteria; // Criteria for address match memset(&addrCriteria, 0, sizeof(addrCriteria)); // Zero out structure addrCriteria.ai_family = AF_UNSPEC; // Any address family addrCriteria.ai_socktype = SOCK_STREAM; // Only stream sockets addrCriteria.ai_protocol = IPPROTO_TCP; // Only TCP protocol // Get address(es) associated with the specified name/service struct addrinfo *addrList; // Holder for list of addresses returned // Modify servAddr contents to reference linked list of addresses int rtnVal = getaddrinfo(addrString, portString, &addrCriteria, &addrList); if (rtnVal != 0) DieWithUserMessage("getaddrinfo() failed", (const char*)gai_strerror(rtnVal)); // Display returned addresses /**for (struct addrinfo *addr = addrList; addr != NULL; addr = addr->ai_next) { PrintSocketAddress(addr->ai_addr, stdout); fputc('\n', stdout); }*///-std=c99 才支持 for()指针语法,但是使用c99的话,经测试其他的getaddrinfo等函数就会出问题,故换成while循环,问题解决。 //是-std=c99 导致netdb h无效了 struct addrinfo *addr = addrList; while (addr != NULL) { PrintSocketAddress(addr->ai_addr, stdout); fputc('\n', stdout); addr = addr->ai_next; } freeaddrinfo(addrList); // Free addrinfo allocated in getaddrinfo() exit(0); }
/* * File: DieWithMessage.h * Author: root * * Created on 2013年11月13日, 下午3:52 */ #ifndef DIEWITHMESSAGE_H #define DIEWITHMESSAGE_H #ifdef __cplusplus extern "C" { #endif #include <stdio.h> #include <stdlib.h> void DieWithUserMessage(const char *msg,const char * detail) { fputs(msg,stderr); fputs(":",stderr); fputs(detail,stderr); fputs("\n",stderr); exit(1); } void DieWithSystemMessage(const char* msg) { perror(msg); exit(1); } #ifdef __cplusplus } #endif #endif /* DIEWITHMESSAGE_H */
附上c语言标准库的资料:
http://www.schweikhardt.net/identifiers.html