From 38eecc722dd2586ab10d5eab5fd172a3caa71817 Mon Sep 17 00:00:00 2001 From: Sergey Yagovtsev Date: Mon, 19 Sep 2016 23:59:55 +0300 Subject: [PATCH] Refactoring of sockets --- include/profiler/easy_socket.h | 18 +- src/easy_socket.cpp | 353 ++++++++++++++------------------- 2 files changed, 165 insertions(+), 206 deletions(-) diff --git a/include/profiler/easy_socket.h b/include/profiler/easy_socket.h index 32b7623..96d584c 100644 --- a/include/profiler/easy_socket.h +++ b/include/profiler/easy_socket.h @@ -40,6 +40,13 @@ along with this program.If not, see . class PROFILER_API EasySocket { public: + +#ifdef _WIN32 + typedef SOCKET socket_t; +#else + typedef int socket_t; +#endif + enum ConnectionState { CONNECTION_STATE_UNKNOWN, @@ -49,13 +56,12 @@ public: }; private: - void checkResult(int result); -#ifdef _WIN32 - typedef SOCKET socket_t; -#else - typedef int socket_t; -#endif + + void checkResult(int result); + bool checkSocket(socket_t s) const; + static int _close(socket_t s); + void setBlocking(socket_t s, bool blocking); socket_t m_socket = 0; socket_t m_replySocket = 0; diff --git a/src/easy_socket.cpp b/src/easy_socket.cpp index 691e56f..82ae7ef 100644 --- a/src/easy_socket.cpp +++ b/src/easy_socket.cpp @@ -18,60 +18,171 @@ along with this program.If not, see . #include "profiler/easy_socket.h" +#include -#ifndef _WIN32 -#include +#ifdef _WIN32 +#pragma comment (lib, "Ws2_32.lib") +#pragma comment (lib, "Mswsock.lib") +#pragma comment (lib, "AdvApi32.lib") +#else #include +#include +#endif + +bool EasySocket::checkSocket(socket_t s) const +{ + return s > 0; +} + +int EasySocket::_close(EasySocket::socket_t s) +{ +#ifdef _WIN32 + return ::closesocket(s); +#else + //TODO + //return close(s); +#endif +} + +void EasySocket::setBlocking(EasySocket::socket_t s, bool blocking) +{ + +#ifdef _WIN32 + u_long iMode = blocking ? 0 : 1;//0 - blocking, 1 - non blocking + ioctlsocket(s, FIONBIO, &iMode); +#else + const int iMode = blocking ? 0 : 1;//0 - blocking, 1 - non blocking + ioctl(s, FIONBIO, (char *)&iMode); +#endif +} int EasySocket::bind(uint16_t portno) { - if(m_socket < 0 ) return -1; + if (!checkSocket(m_socket)) return -1; + struct sockaddr_in serv_addr; - bzero((char *) &serv_addr, sizeof(serv_addr)); + memset(&serv_addr, 0, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = INADDR_ANY; serv_addr.sin_port = htons(portno); - return ::bind(m_socket, (struct sockaddr *) &serv_addr, sizeof(serv_addr)); + auto res = ::bind(m_socket, (struct sockaddr *) &serv_addr, sizeof(serv_addr)); + return res; } void EasySocket::flush() { if (m_socket){ - close(m_socket); + _close(m_socket); } if (m_replySocket != m_socket){ - close(m_replySocket); + _close(m_replySocket); } +#ifdef _WIN32 m_socket = 0; m_replySocket = 0; +#endif } + +void EasySocket::checkResult(int result) +{ +// printf("Errno: %s\n", strerror(errno)); + if(result >= 0){ + m_state = CONNECTION_STATE_SUCCESS; + return; + }else if(result == -1){ + + + int error_code = 0; + +#ifdef _WIN32 + error_code = WSAGetLastError(); + const int CONNECTION_ABORTED = WSAECONNABORTED; + const int CONNECTION_RESET = WSAECONNRESET; +#else + error_code = errno; + const int CONNECTION_ABORTED = ECONNABORTED; + const int CONNECTION_RESET = ECONNRESET; +#endif + + switch(error_code) + { + case CONNECTION_ABORTED: + case CONNECTION_RESET: + m_state = CONNECTION_STATE_DISCONNECTED; + break; + default: + break; + } + } +} + void EasySocket::init() { - m_socket = socket(AF_INET, SOCK_STREAM, 0); + if (wsaret == 0) + { + int protocol = 0; +#ifdef _WIN32 + protocol = IPPROTO_TCP; +#endif + m_socket = socket(AF_INET, SOCK_STREAM, protocol); + if (!checkSocket(m_socket)) { + return; + } + }else + return; + + setBlocking(m_socket,true); + + int opt = 1; + setsockopt(m_socket, SOL_SOCKET, SO_REUSEADDR, (const char *)&opt, sizeof(opt)); } EasySocket::EasySocket() { +#ifdef _WIN32 + WSADATA wsaData; + wsaret = WSAStartup(0x101, &wsaData); +#else + wsaret = 0; +#endif init(); +#ifndef _WIN32 + wsaret = 1; +#endif } EasySocket::~EasySocket() { flush(); +#ifdef _WIN32 + if (wsaret == 0) + WSACleanup(); +#endif } int EasySocket::send(const void *buf, size_t nbyte) { - if(m_replySocket <= 0) return -1; - int res = ::write(m_replySocket,buf,nbyte); + if(!checkSocket(m_replySocket)) return -1; + int res = 0; +#ifdef _WIN32 + res = ::send(m_replySocket, (const char*)buf, nbyte, 0); +#else + res = ::write(m_replySocket,buf,nbyte); +#endif checkResult(res); return res; } int EasySocket::receive(void *buf, size_t nbyte) { - if(m_replySocket <= 0) return -1; - int res = ::read(m_replySocket,buf,nbyte); + if(!checkSocket(m_replySocket)) return -1; + int res = 0; +#ifdef _WIN32 + res = ::recv(m_replySocket, (char*)buf, nbyte, 0); +#else + res = ::read(m_replySocket,buf,nbyte); +#endif + checkResult(res); if (res == 0){ m_state = CONNECTION_STATE_DISCONNECTED; @@ -81,7 +192,7 @@ int EasySocket::receive(void *buf, size_t nbyte) int EasySocket::listen(int count) { - if(m_socket < 0 ) return -1; + if(!checkSocket(m_socket)) return -1; int res = ::listen(m_socket,count); checkResult(res); return res; @@ -89,30 +200,28 @@ int EasySocket::listen(int count) int EasySocket::accept() { - if(m_socket < 0 ) return -1; + if(!checkSocket(m_socket)) return -1; m_replySocket = ::accept(m_socket,nullptr,nullptr); checkResult(m_replySocket); + if(checkSocket(m_replySocket)) + { + int send_buffer = 64*1024*1024; + int send_buffer_sizeof = sizeof(int); + setsockopt(m_replySocket, SOL_SOCKET, SO_SNDBUF, (char*)&send_buffer, send_buffer_sizeof); + //int flag = 1; + //int result = setsockopt(m_replySocket,IPPROTO_TCP,TCP_NODELAY,(char *)&flag,sizeof(int)); + + //setBlocking(m_replySocket,true); + } return m_replySocket; } -bool EasySocket::setAddress(const char *serv, uint16_t portno) -{ - server = gethostbyname(serv); - if (server == NULL) { - return false; - //fprintf(stderr,"ERROR, no such host\n"); - } - bzero((char *) &serv_addr, sizeof(serv_addr)); - serv_addr.sin_family = AF_INET; - bcopy((char *)server->h_addr, - (char *)&serv_addr.sin_addr.s_addr, - server->h_length); - serv_addr.sin_port = htons(portno); +#ifndef _WIN32 +#include +#include - return true; -} int EasySocket::connect() { @@ -134,137 +243,26 @@ int EasySocket::connect() } return res; } -#include -void EasySocket::checkResult(int result) -{ - if(result >= 0){ - m_state = CONNECTION_STATE_SUCCESS; - return; - }else if(result == -1){ - //printf("Errno: %s\n", strerror(errno)); - switch(errno){ - case ECONNABORTED: - case ECONNRESET: - m_state = CONNECTION_STATE_DISCONNECTED; - break; - default: - break; - } +bool EasySocket::setAddress(const char *serv, uint16_t portno) +{ + server = gethostbyname(serv); + if (server == NULL) { + return false; + //fprintf(stderr,"ERROR, no such host\n"); } + bzero((char *) &serv_addr, sizeof(serv_addr)); + serv_addr.sin_family = AF_INET; + bcopy((char *)server->h_addr, + (char *)&serv_addr.sin_addr.s_addr, + server->h_length); + serv_addr.sin_port = htons(portno); + + return true; } #else -#pragma comment (lib, "Ws2_32.lib") -#pragma comment (lib, "Mswsock.lib") -#pragma comment (lib, "AdvApi32.lib") - -void EasySocket::checkResult(int result) -{ - if (result >= 0){ - m_state = CONNECTION_STATE_SUCCESS; - return; - } - else if (result == -1){ - int error_code = WSAGetLastError(); - //printf("Errno: %s\n", strerror(errno)); - switch (error_code){ - case WSAECONNABORTED: - case WSAECONNRESET: - m_state = CONNECTION_STATE_DISCONNECTED; - break; - default: - break; - } - - } -} - -void EasySocket::flush() -{ - if (m_socket){ - closesocket(m_socket); - } - if (m_replySocket != m_socket){ - closesocket(m_replySocket); - } - m_socket = INVALID_SOCKET; - m_replySocket = INVALID_SOCKET; -} -void EasySocket::init() -{ - if (wsaret == 0) - { - m_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);; - if (m_socket == INVALID_SOCKET) { - return; - } - } - - u_long iMode = 0;//0 - blocking, 1 - non blocking - ioctlsocket(m_socket, FIONBIO, &iMode); - - int opt = 1; - setsockopt(m_socket, SOL_SOCKET, SO_REUSEADDR, (const char *)&opt, sizeof(opt)); -} - -EasySocket::EasySocket() -{ - // socket - WSADATA wsaData; - wsaret = WSAStartup(0x101, &wsaData); - init(); -} - -EasySocket::~EasySocket() -{ - flush(); - if (wsaret == 0) - WSACleanup(); -} - -int EasySocket::send(const void *buf, size_t nbyte) -{ - if (m_replySocket <= 0){ - return -1; - } - - int res = ::send(m_replySocket, (const char*)buf, nbyte, 0); - checkResult(res); - return res; -} - -#include - -int EasySocket::receive(void *buf, size_t nbyte) -{ - if (m_replySocket <= 0){ - return -1; - } - - int res = ::recv(m_replySocket, (char*)buf, nbyte, 0); - checkResult(res); - if (res == 0){ - m_state = CONNECTION_STATE_DISCONNECTED; - } - - /** - if (res == SOCKET_ERROR) - { - LPWSTR *s = NULL; - int err = WSAGetLastError(); - FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, err, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPWSTR)&s, 0, NULL); - printf("%S\n", s); - LocalFree(s); - } - /**/ - return res; -} - bool EasySocket::setAddress(const char *serv, uint16_t portno) { ZeroMemory(&hints, sizeof(hints)); @@ -303,53 +301,8 @@ int EasySocket::connect() setsockopt(m_socket, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(struct timeval)); m_replySocket = m_socket; - + return iResult; } - -int EasySocket::listen(int count) -{ - if (m_socket < 0) return -1; - int res = ::listen(m_socket, count); - checkResult(res); - return res; -} - -int EasySocket::accept() -{ - if (m_socket < 0) return -1; - m_replySocket = ::accept(m_socket, nullptr, nullptr); - - int send_buffer = 64 * 1024*1024; // 64 MB - int send_buffer_sizeof = sizeof(int); - setsockopt(m_replySocket, SOL_SOCKET, SO_SNDBUF, (char*)&send_buffer, send_buffer_sizeof); - - //int flag = 1; - //int result = setsockopt(m_replySocket,IPPROTO_TCP,TCP_NODELAY,(char *)&flag,sizeof(int)); - - u_long iMode = 0;//0 - blocking, 1 - non blocking - ioctlsocket(m_replySocket, FIONBIO, &iMode); - - return (int)m_replySocket; -} - -int EasySocket::bind(uint16_t portno) -{ - if (m_socket < 0) return -1; - struct sockaddr_in serv_addr; - memset(&serv_addr, 0, sizeof(serv_addr)); - serv_addr.sin_family = AF_INET; - serv_addr.sin_addr.s_addr = INADDR_ANY; - serv_addr.sin_port = htons(portno); - auto res = ::bind(m_socket, (struct sockaddr *) &serv_addr, sizeof(serv_addr)); - if (res == SOCKET_ERROR) - { - printf("bind failed with error %u\n", WSAGetLastError()); - return -1; - } - return res; -} - - #endif