123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112 |
- #include "IConnection.h"
- #include "IConnectionServer.h"
- #include "IConnection.inl"
-
- #include <cstring>
- #include <iostream>
-
- #if defined TARGET_OS_Linux || defined TARGET_OS_MacOS
- #include <netinet/in.h>
- #include <netinet/tcp.h>
- #include <netdb.h>
- #include <cerrno>
- #elif defined TARGET_OS_Windows
- #else
- #endif
-
- namespace Socket {
- class CConnectionServer final : public TConnection<IConnectionServer>
- {
- 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<const char*>(&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<unsigned short>(port));
- localHostAddress.sin_addr.s_addr = htonl(INADDR_ANY);
-
- if (bind(m_socket, reinterpret_cast<struct sockaddr*>(&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<struct sockaddr*>(&clientAddress), &clientAddressSize));
- if (clientSocket == -1) { return nullptr; }
- return new TConnection<IConnection>(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<sockaddr*>(&socketInfo), &socketInfoLength) == -1) { return false; }
-
- port = size_t(ntohs(socketInfo.sin_port));
- return true;
- }
- };
-
- IConnectionServer* createConnectionServer() { return new CConnectionServer(); }
- } // namespace Socket
|