#ifndef __POSIX_SOCKET_TEMPLATE_H__ #define __POSIX_SOCKET_TEMPLATE_H__ #include #include #if !defined(WIN32) #include #include #endif #include /* A template for opening a non-blocking POSIX socket. */ int open_nb_socket(const char* addr, const char* port) { struct addrinfo hints = {0}; hints.ai_family = AF_UNSPEC; /* IPv4 or IPv6 */ hints.ai_socktype = SOCK_STREAM; /* Must be TCP */ int sockfd = -1; int rv; struct addrinfo *p, *servinfo; /* get address information */ rv = getaddrinfo(addr, port, &hints, &servinfo); if(rv != 0) { fprintf(stderr, "Failed to open socket (getaddrinfo): %s\n", gai_strerror(rv)); return -1; } /* open the first possible socket */ for(p = servinfo; p != NULL; p = p->ai_next) { sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol); if (sockfd == -1) continue; /* connect to server */ rv = connect(sockfd, servinfo->ai_addr, servinfo->ai_addrlen); if(rv == -1) continue; break; } /* free servinfo */ freeaddrinfo(servinfo); /* make non-blocking */ #if !defined(WIN32) if (sockfd != -1) fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFL) | O_NONBLOCK); #else if (sockfd != INVALID_SOCKET) { int iMode = 1; ioctlsocket(sockfd, FIONBIO, &iMode); } #endif /* return the new socket fd */ return sockfd; } #endif