X Tutup
#include "Socket.h" namespace HttpServer { int Socket::Startup() { #ifdef WIN32 unsigned short version = MAKEWORD(2, 2); ::WSADATA wsaData = {0}; return ::WSAStartup(version, &wsaData); #elif POSIX return 0; #else #error "Undefine platform" #endif } int Socket::Cleanup() { #ifdef WIN32 return ::WSACleanup(); #elif POSIX return 0; #else #error "Undefine platform" #endif } Socket::Socket(): socket_handle(~0) { } Socket::Socket(const System::native_socket_type handle) : socket_handle(handle) { } Socket::Socket(const Socket &obj) : socket_handle(obj.socket_handle) { } Socket::Socket(Socket &&that) : socket_handle(that.socket_handle) { that.socket_handle = ~0; } System::native_socket_type Socket::open() { close(); socket_handle = ::socket(AF_INET, SOCK_STREAM, 0); return socket_handle; } int Socket::close() { if (is_open() ) { #ifdef WIN32 int result = ::closesocket(socket_handle); #elif POSIX int result = ::close(socket_handle); #else #error "Undefine platform" #endif if (0 == result) { socket_handle = ~0; } return result; } return ~0; } int Socket::bind(const int port) const { ::sockaddr_in sock_addr = {0}; sock_addr.sin_family = AF_INET; sock_addr.sin_port = htons(port); sock_addr.sin_addr.s_addr = ::htonl(INADDR_ANY); return ::bind(socket_handle, reinterpret_cast(&sock_addr), sizeof(sockaddr_in) ); } int Socket::listen() const { return ::listen(socket_handle, SOMAXCONN); } Socket Socket::accept() const { #ifdef WIN32 System::native_socket_type client_socket = ::accept(socket_handle, static_cast(nullptr), static_cast(nullptr) ); #elif POSIX System::native_socket_type client_socket = ::accept(socket_handle, static_cast(nullptr), static_cast(nullptr) ); #else #error "Undefine platform" #endif return Socket(client_socket); } Socket Socket::nonblock_accept() const { System::native_socket_type client_socket = ~0; #ifdef WIN32 WSAPOLLFD event = {0}; event.fd = socket_handle; event.events = POLLRDNORM; if (1 == ::WSAPoll(&event, 1, ~0) && event.revents | POLLRDNORM) { client_socket = ::accept(socket_handle, static_cast(nullptr), static_cast(nullptr) ); } #elif POSIX struct ::pollfd event = {0}; event.fd = socket_handle; event.events = POLLIN; if (1 == ::poll(&event, 1, ~0) && event.revents | POLLIN) { client_socket = ::accept(socket_handle, static_cast(nullptr), static_cast(nullptr) ); } #else #error "Undefine platform" #endif return Socket(client_socket); } Socket Socket::nonblock_accept(const std::chrono::milliseconds &timeWait) const { System::native_socket_type client_socket = ~0; #ifdef WIN32 WSAPOLLFD event = {0}; event.fd = socket_handle; event.events = POLLRDNORM; if (1 == ::WSAPoll(&event, 1, timeWait.count() ) && event.revents | POLLRDNORM) { client_socket = ::accept(socket_handle, static_cast(nullptr), static_cast(nullptr) ); } #elif POSIX struct ::pollfd event = {0}; event.fd = socket_handle; event.events = POLLIN; if (1 == ::poll(&event, 1, timeWait.count() ) && event.revents | POLLIN) { client_socket = ::accept(socket_handle, static_cast(nullptr), static_cast(nullptr) ); } #else #error "Undefine platform" #endif return Socket(client_socket); } int Socket::shutdown() const { if (is_open() ) { #ifdef WIN32 return ::shutdown(socket_handle, SD_BOTH); #elif POSIX return ::shutdown(socket_handle, SHUT_RDWR); #else #error "Undefine platform" #endif } return -1; } bool Socket::nonblock(const bool isNonBlock) const { #ifdef WIN32 unsigned long value = isNonBlock; return 0 == ::ioctlsocket(socket_handle, FIONBIO, &value); #elif POSIX return -1 != ::fcntl(socket_handle, F_SETFL, isNonBlock ? O_NONBLOCK : O_SYNC); #else #error "Undefine platform" #endif } /* bool Socket::is_nonblock() const { #ifdef WIN32 #elif POSIX int flags = ::fcntl(socket_handle, F_GETFL, 0); return (flags != -1) && (flags & O_NONBLOCK); #else #error "Undefine platform" #endif }*/ size_t Socket::recv(std::vector &buf) const { #ifdef WIN32 return ::recv(socket_handle, buf.data(), buf.size(), 0); #elif POSIX return ::recv(socket_handle, buf.data(), buf.size(), MSG_NOSIGNAL); #else #error "Undefine platform" #endif } size_t Socket::nonblock_recv(std::vector &buf, const std::chrono::milliseconds &timeWait) const { size_t recv_len = ~0; #ifdef WIN32 WSAPOLLFD event = {0}; event.fd = socket_handle; event.events = POLLRDNORM; if (1 == ::WSAPoll(&event, 1, timeWait.count() ) && event.revents | POLLRDNORM) { recv_len = ::recv(socket_handle, buf.data(), buf.size(), 0); } #elif POSIX struct ::pollfd event = {0}; event.fd = socket_handle; event.events = POLLIN; if (1 == ::poll(&event, 1, timeWait.count() ) && event.revents | POLLIN) { recv_len = ::recv(socket_handle, buf.data(), buf.size(), MSG_NOSIGNAL); } #else #error "Undefine platform" #endif return recv_len; } size_t Socket::send(const std::string &buf) const { #ifdef WIN32 return ::send(socket_handle, buf.data(), buf.length(), 0); #elif POSIX return ::send(socket_handle, buf.data(), buf.length(), MSG_WAITALL | MSG_NOSIGNAL); #else #error "Undefine platform" #endif } size_t Socket::send(const std::vector &buf, const size_t length) const { #ifdef WIN32 return ::send(socket_handle, buf.data(), length, 0); #elif POSIX return ::send(socket_handle, buf.data(), length, MSG_WAITALL | MSG_NOSIGNAL); #else #error "Undefine platform" #endif } size_t Socket::nonblock_send(const std::string &buf, const std::chrono::milliseconds &timeWait) const { size_t send_len = ~0; #ifdef WIN32 WSAPOLLFD event = {0}; event.fd = socket_handle; event.events = POLLWRNORM; if (1 == ::WSAPoll(&event, 1, timeWait.count() ) && event.revents | POLLWRNORM) { send_len = ::send(socket_handle, buf.data(), buf.length(), 0); } #elif POSIX struct ::pollfd event = {0}; event.fd = socket_handle; event.events = POLLOUT; if (1 == ::poll(&event, 1, timeWait.count() ) && event.revents | POLLOUT) { send_len = ::send(socket_handle, buf.data(), buf.length(), MSG_NOSIGNAL); } #else #error "Undefine platform" #endif return send_len; } size_t Socket::nonblock_send(const std::vector &buf, const size_t length, const std::chrono::milliseconds &timeWait) const { size_t send_len = ~0; #ifdef WIN32 WSAPOLLFD event = {0}; event.fd = socket_handle; event.events = POLLWRNORM; if (1 == ::WSAPoll(&event, 1, timeWait.count() ) && event.revents | POLLWRNORM) { send_len = ::send(socket_handle, buf.data(), length, 0); } #elif POSIX struct ::pollfd event = {0}; event.fd = socket_handle; event.events = POLLOUT; if (1 == ::poll(&event, 1, timeWait.count() ) && event.revents | POLLOUT) { send_len = ::send(socket_handle, buf.data(), length, MSG_WAITALL | MSG_NOSIGNAL); } #else #error "Undefine platform" #endif return send_len; } Socket &Socket::operator=(const Socket s) { socket_handle = s.socket_handle; return *this; } };
X Tutup