/* ** JNetLib ** Copyright (C) 2000-2013 Nullsoft, Inc. ** Author: Justin Frankel, Ben Allison ** File: listen.cpp - JNL TCP listen implementation ** License: see jnetlib.h */ #include "netinc.h" #include "util.h" #include "listen.h" #include "foundation/error.h" JNL_Listen::JNL_Listen() { m_port=0; m_socket=-1; } int JNL_Listen::Initialize(unsigned short port, sockaddr *which_interface, int family) { m_port = port; char portString[32] = {0}; sprintf(portString, "%d", (int)port); addrinfo *res; addrinfo hints; memset(&hints, 0, sizeof(hints)); hints.ai_family = family; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_NUMERICHOST | AI_PASSIVE; hints.ai_addr = which_interface?which_interface:INADDR_ANY; if (getaddrinfo(NULL, portString, &hints, &res) == 0) { int ret = Initialize(res, 0); freeaddrinfo(res); return ret; } else { return NErr_Error; } } int JNL_Listen::Initialize(addrinfo *address, size_t index) { addrinfo *res = address; while (index--) { res = res->ai_next; if (!res) return NErr_EndOfEnumeration; } m_socket = ::socket(res->ai_family,res->ai_socktype, res->ai_protocol); if (m_socket < 0) { freeaddrinfo(res); return NErr_Error; } else { SET_SOCK_BLOCK(m_socket,0); #ifndef _WIN32 int bflag = 1; setsockopt(m_socket, SOL_SOCKET, SO_REUSEADDR, &bflag, sizeof(bflag)); #endif if (::bind(m_socket, res->ai_addr, (int)res->ai_addrlen)) { closesocket(m_socket); m_socket=-1; return NErr_Error; } else if (::listen(m_socket,8)==-1) { closesocket(m_socket); m_socket=-1; return NErr_Error; } } return NErr_Success; } JNL_Listen::~JNL_Listen() { if (m_socket>=0) { closesocket(m_socket); } } JNL_Connection *JNL_Listen::get_connect(size_t sendbufsize, size_t recvbufsize) { if (m_socket < 0) { return NULL; } sockaddr_storage saddr; socklen_t length = sizeof(saddr); SOCKET s = accept(m_socket, (sockaddr *)&saddr, &length); if (s != -1) { JNL_Connection *c=new JNL_Connection(NULL,sendbufsize, recvbufsize); c->connect(s, (sockaddr *)&saddr, length); return c; } return NULL; } socklen_t JNL_Listen::get_address(sockaddr* address, socklen_t *address_len) { return getsockname(m_socket, address, address_len); } unsigned short JNL_Listen::get_port() { if (!m_port) { sockaddr_in address; socklen_t namelen = sizeof(address); if (getsockname(m_socket, (sockaddr *)&address, &namelen) == 0) m_port = ntohs(address.sin_port); } return m_port; }