socket_t client_socket (char const * host, char const * port) { socket_t sock=INVALID_SOCKET; struct addrinfo * info=make_addrinfo(host, port); if (info) { char hostname[NI_MAXHOST]; char portname[NI_MAXSERV]; if (!setnameinfo(info->ai_addr, info->ai_addrlen, hostname, portname)) goto END; NANOLOG("[%s:%s]\n", hostname, portname); sock=socket(info->ai_family, info->ai_socktype, info->ai_protocol); if (sock==INVALID_SOCKET) { NANOLOG("socket failed <%d>\n", nanonet_error()); goto END; } if (connect(sock, info->ai_addr, info->ai_addrlen)==INVALID_SOCKET) { NANOLOG("connect failed <%d>\n", nanonet_error()); close_socket_t(sock); sock=INVALID_SOCKET; goto END; } } else NANOLOG("make_addrinfo failed <%d>\n", nanonet_error()); END: freeaddrinfo(info); return sock; }
socket_t vsingle_accept(socket_t sock, bool (*serv)(socket_t, va_list), ...) { bool r; if (sock==INVALID_SOCKET) return sock; do { struct sockaddr_in addr; socklen_t len = sizeof(addr); socket_t acc=accept(sock, (struct sockaddr*)&addr, &len); if (acc==INVALID_SOCKET) { NANOLOG("accept failed <%d>\n", nanonet_error()); r=false; } else { char * hostport = getnameinfo_as_string((struct sockaddr const*)&addr, len); NANOLOG("accept [%s] <- [%s:%d]\n", hostport , inet_ntoa(addr.sin_addr), ntohs(addr.sin_port)); free(hostport); { va_list ap; va_start(ap, serv); r=serv(acc, ap); va_end(ap); } } close_socket_t(acc); } while (r); // end if serv is fail return sock; }
socket_t server_socket (char const * host, char const * port) { socket_t sock=INVALID_SOCKET; struct addrinfo * info=make_addrinfo(host, port); if (info) { char hostname[NI_MAXHOST]; char portname[NI_MAXSERV]; if (!setnameinfo(info->ai_addr, info->ai_addrlen, hostname, portname)) goto END; NANOLOG("server_socket [%s:%s]\n", hostname, portname); sock=socket(info->ai_family, info->ai_socktype, info->ai_protocol); if (sock==INVALID_SOCKET) { NANOLOG("socket failed <%d>\n", nanonet_error()); goto END; } { char const enable = '1'; if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int))==SOCKET_ERROR) { NANOLOG("setsockopt <%s>\n", nanonet_error_tostring(nanonet_error())); close_socket_t(sock); sock=INVALID_SOCKET; goto END; } } if (bind(sock, info->ai_addr, info->ai_addrlen)) { NANOLOG("bind failed <%d>\n", nanonet_error()); close_socket_t(sock); sock=INVALID_SOCKET; goto END; } if (listen(sock, SOMAXCONN)) { NANOLOG("listen failed <%d>\n", nanonet_error()); close_socket_t(sock); sock=INVALID_SOCKET; goto END; } } else NANOLOG("make_addrinfo failed <%d>\n", nanonet_error()); END: freeaddrinfo(info); return sock; }
basic_socket::~basic_socket() { close_socket_t(sd_); }