#include "IConnection.h" #include "IConnectionServer.h" #include "IConnection.inl" #include #include #if defined TARGET_OS_Linux || defined TARGET_OS_MacOS #include #include #include #include #elif defined TARGET_OS_Windows #else #endif namespace Socket { class CConnectionServer final : public TConnection { public: bool listen(const size_t port) override { if (!open()) { return false; } int reuseAddress = 1; #if defined TARGET_OS_Windows setsockopt(m_socket, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast(&reuseAddress), sizeof(reuseAddress)); #else ::setsockopt(m_socket, SOL_SOCKET, SO_REUSEADDR, &reuseAddress, sizeof(reuseAddress)); #endif struct sockaddr_in localHostAddress; memset(&localHostAddress, 0, sizeof(localHostAddress)); localHostAddress.sin_family = AF_INET; localHostAddress.sin_port = htons(static_cast(port)); localHostAddress.sin_addr.s_addr = htonl(INADDR_ANY); if (bind(m_socket, reinterpret_cast(&localHostAddress), sizeof(localHostAddress)) == -1) { /* switch(errno) { case EBADF: std::cout << "EBADF" << std::endl; break; case ENOTSOCK: std::cout << "ENOTSOCK" << std::endl; break; case EADDRINUSE: std::cout << "EADDRINUSE" << std::endl; break; case EINVAL: std::cout << "EINVAL" << std::endl; break; case EROFS: std::cout << "EROFS" << std::endl; break; case EFAULT: std::cout << "EFAULT" << std::endl; break; case ENAMETOOLONG: std::cout << "ENAMETOOLONG" << std::endl; break; case ENOENT: std::cout << "ENOENT" << std::endl; break; case ENOMEM: std::cout << "ENOMEM" << std::endl; break; case ENOTDIR: std::cout << "ENOTDIR" << std::endl; break; case EACCES: std::cout << "EACCES" << std::endl; break; case ELOOP: std::cout << "ELOOP" << std::endl; break; default: std::cout << "Bind_unknown" << std::endl; } */ return false; } if (::listen(m_socket, 32) == -1) { /* switch(errno) { case EADDRINUSE: std::cout << "EADDRINUSE" << std::endl; break; case EBADF: std::cout << "EBADF" << std::endl; break; case ENOTSOCK: std::cout << "ENOTSOCK" << std::endl; break; case EOPNOTSUPP: std::cout << "EOPNOTSUPP" << std::endl; break; default: std::cout << "Listen_unknown" << std::endl; } */ return false; } return true; } IConnection* accept() override { struct sockaddr_in clientAddress; #if defined TARGET_OS_Linux || defined TARGET_OS_MacOS socklen_t clientAddressSize = sizeof(clientAddress); #elif defined TARGET_OS_Windows int clientAddressSize = sizeof(clientAddress); #else #endif const int clientSocket = int(::accept(m_socket, reinterpret_cast(&clientAddress), &clientAddressSize)); if (clientSocket == -1) { return nullptr; } return new TConnection(int(clientSocket)); } bool getSocketPort(size_t& port) override { struct sockaddr_in socketInfo; #if defined TARGET_OS_Linux || defined TARGET_OS_MacOS socklen_t socketInfoLength = sizeof(socketInfo); #elif defined TARGET_OS_Windows int socketInfoLength = sizeof(socketInfo); #endif if (getsockname(m_socket, reinterpret_cast(&socketInfo), &socketInfoLength) == -1) { return false; } port = size_t(ntohs(socketInfo.sin_port)); return true; } }; IConnectionServer* createConnectionServer() { return new CConnectionServer(); } } // namespace Socket