59 lines
1.4 KiB
C
59 lines
1.4 KiB
C
#ifndef __POSIX_SOCKET_TEMPLATE_H__
|
|
#define __POSIX_SOCKET_TEMPLATE_H__
|
|
|
|
#include <stdio.h>
|
|
#include <sys/types.h>
|
|
#if !defined(WIN32)
|
|
#include <sys/socket.h>
|
|
#include <netdb.h>
|
|
#endif
|
|
#include <fcntl.h>
|
|
|
|
/*
|
|
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 |