Compare commits
	
		
			7 Commits
		
	
	
		
			user/bserg
			...
			feature/wi
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | a9ffa7da11 | ||
|  | 44e5ab7f7d | ||
|  | 280d1d7366 | ||
|  | 37e899e872 | ||
|  | 644d988c29 | ||
|  | b68a4c26f2 | ||
|  | c3bf260330 | 
| @@ -13,6 +13,7 @@ | |||||||
| #include <sstream> | #include <sstream> | ||||||
| #include <queue> | #include <queue> | ||||||
| #include <ixwebsocket/IXWebSocket.h> | #include <ixwebsocket/IXWebSocket.h> | ||||||
|  | #include <ixwebsocket/IXSocket.h> | ||||||
|  |  | ||||||
| #include "nlohmann/json.hpp" | #include "nlohmann/json.hpp" | ||||||
|  |  | ||||||
| @@ -160,11 +161,9 @@ namespace | |||||||
|  |  | ||||||
|     void interactiveMain() |     void interactiveMain() | ||||||
|     { |     { | ||||||
|         std::string user(getenv("USER")); |         std::string user("foo"); | ||||||
|  |  | ||||||
|         WebSocketChat webSocketChat(user); |  | ||||||
|  |  | ||||||
|         std::cout << "Type Ctrl-D to exit prompt..." << std::endl; |         std::cout << "Type Ctrl-D to exit prompt..." << std::endl; | ||||||
|  |         WebSocketChat webSocketChat(user); | ||||||
|         webSocketChat.start(); |         webSocketChat.start(); | ||||||
|  |  | ||||||
|         while (true) |         while (true) | ||||||
| @@ -188,6 +187,9 @@ namespace | |||||||
|  |  | ||||||
| int main() | int main() | ||||||
| { | { | ||||||
|  |     std::cout << "main starting" << std::endl; | ||||||
|  |     Socket::init(); | ||||||
|  |     std::cout << "socket initialized" << std::endl; | ||||||
|     interactiveMain(); |     interactiveMain(); | ||||||
|     return 0; |     return 0; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -6,22 +6,34 @@ | |||||||
|  |  | ||||||
| #include "IXSocket.h" | #include "IXSocket.h" | ||||||
|  |  | ||||||
| #include <netdb.h> | #ifdef _WIN32 | ||||||
| #include <netinet/tcp.h> | # include <basetsd.h> | ||||||
|  | # include <WinSock2.h> | ||||||
|  | # include <ws2def.h> | ||||||
|  | # include <WS2tcpip.h> | ||||||
|  | # include <io.h> | ||||||
|  | #pragma comment(lib, "ws2_32") | ||||||
|  | # include <io.h> | ||||||
|  | #else | ||||||
|  | # include <unistd.h> | ||||||
|  | # include <errno.h> | ||||||
|  | # include <netdb.h> | ||||||
|  | # include <netinet/tcp.h> | ||||||
|  | # include <sys/socket.h> | ||||||
|  | # include <sys/time.h> | ||||||
|  | # include <sys/select.h> | ||||||
|  | # include <sys/stat.h> | ||||||
|  | #endif | ||||||
|  |  | ||||||
| #include <stdio.h> | #include <stdio.h> | ||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
| #include <string.h> | #include <string.h> | ||||||
| #include <sys/socket.h> |  | ||||||
| #include <sys/time.h> |  | ||||||
| #include <sys/types.h> |  | ||||||
| #include <unistd.h> |  | ||||||
| #include <stdint.h> |  | ||||||
| #include <sys/select.h> |  | ||||||
| #include <errno.h> |  | ||||||
| #include <sys/types.h> |  | ||||||
| #include <sys/stat.h> |  | ||||||
| #include <fcntl.h> |  | ||||||
| #include <assert.h> | #include <assert.h> | ||||||
|  | #include <stdint.h> | ||||||
|  | #include <fcntl.h> | ||||||
|  | #include <sys/types.h> | ||||||
|  |  | ||||||
|  | #include <algorithm> | ||||||
|  |  | ||||||
| // | // | ||||||
| // Linux/Android has a special type of virtual files. select(2) will react | // Linux/Android has a special type of virtual files. select(2) will react | ||||||
| @@ -35,7 +47,7 @@ | |||||||
| // cf Android/Kernel table here  | // cf Android/Kernel table here  | ||||||
| // https://android.stackexchange.com/questions/51651/which-android-runs-which-linux-kernel | // https://android.stackexchange.com/questions/51651/which-android-runs-which-linux-kernel | ||||||
| // | // | ||||||
| #ifndef __APPLE__ | #ifdef __linux__ | ||||||
| # include <sys/eventfd.h> | # include <sys/eventfd.h> | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| @@ -51,7 +63,7 @@ namespace ix | |||||||
|         _sockfd(-1), |         _sockfd(-1), | ||||||
|         _eventfd(-1) |         _eventfd(-1) | ||||||
|     { |     { | ||||||
| #ifndef __APPLE__ | #ifdef __linux__ | ||||||
|         _eventfd = eventfd(0, 0); |         _eventfd = eventfd(0, 0); | ||||||
|         assert(_eventfd != -1 && "Panic - eventfd not functioning on this platform"); |         assert(_eventfd != -1 && "Panic - eventfd not functioning on this platform"); | ||||||
| #endif | #endif | ||||||
| @@ -61,14 +73,14 @@ namespace ix | |||||||
|     { |     { | ||||||
|         close(); |         close(); | ||||||
|  |  | ||||||
| #ifndef __APPLE__ | #ifdef __linux__ | ||||||
|         ::close(_eventfd); |         ::close(_eventfd); | ||||||
| #endif | #endif | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     bool connectToAddress(const struct addrinfo *address,  |     bool Socket::connectToAddress(const struct addrinfo *address,  | ||||||
|                           int& sockfd, |                                   int& sockfd, | ||||||
|                           std::string& errMsg) |                                   std::string& errMsg) | ||||||
|     { |     { | ||||||
|         sockfd = -1; |         sockfd = -1; | ||||||
|  |  | ||||||
| @@ -84,7 +96,7 @@ namespace ix | |||||||
|         int maxRetries = 3; |         int maxRetries = 3; | ||||||
|         for (int i = 0; i < maxRetries; ++i) |         for (int i = 0; i < maxRetries; ++i) | ||||||
|         { |         { | ||||||
|             if (connect(fd, address->ai_addr, address->ai_addrlen) != -1) |             if (::connect(fd, address->ai_addr, address->ai_addrlen) != -1) | ||||||
|             { |             { | ||||||
|                 sockfd = fd; |                 sockfd = fd; | ||||||
|                 return true; |                 return true; | ||||||
| @@ -94,7 +106,7 @@ namespace ix | |||||||
|             if (errno != EINTR) break; |             if (errno != EINTR) break; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         ::close(fd); |         closeSocket(fd); | ||||||
|         sockfd = -1; |         sockfd = -1; | ||||||
|         errMsg = strerror(errno); |         errMsg = strerror(errno); | ||||||
|         return false; |         return false; | ||||||
| @@ -142,7 +154,13 @@ namespace ix | |||||||
|     { |     { | ||||||
|         int flag = 1; |         int flag = 1; | ||||||
|         setsockopt(_sockfd, IPPROTO_TCP, TCP_NODELAY, (char*) &flag, sizeof(flag)); // Disable Nagle's algorithm |         setsockopt(_sockfd, IPPROTO_TCP, TCP_NODELAY, (char*) &flag, sizeof(flag)); // Disable Nagle's algorithm | ||||||
|  |  | ||||||
|  | #ifdef _WIN32 | ||||||
|  |         unsigned long nonblocking = 1; | ||||||
|  |         ioctlsocket(_sockfd, FIONBIO, &nonblocking); | ||||||
|  | #else | ||||||
|         fcntl(_sockfd, F_SETFL, O_NONBLOCK); // make socket non blocking |         fcntl(_sockfd, F_SETFL, O_NONBLOCK); // make socket non blocking | ||||||
|  | #endif | ||||||
|  |  | ||||||
| #ifdef SO_NOSIGPIPE | #ifdef SO_NOSIGPIPE | ||||||
|         int value = 1; |         int value = 1; | ||||||
| @@ -163,12 +181,12 @@ namespace ix | |||||||
|         FD_ZERO(&rfds); |         FD_ZERO(&rfds); | ||||||
|         FD_SET(_sockfd, &rfds); |         FD_SET(_sockfd, &rfds); | ||||||
|  |  | ||||||
| #ifndef __APPLE__ | #ifdef __linux__ | ||||||
|         FD_SET(_eventfd, &rfds); |         FD_SET(_eventfd, &rfds); | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|         int sockfd = _sockfd; |         int sockfd = _sockfd; | ||||||
|         int nfds = std::max(sockfd, _eventfd); |         int nfds = (std::max)(sockfd, _eventfd); | ||||||
|         select(nfds + 1, &rfds, nullptr, nullptr, nullptr); |         select(nfds + 1, &rfds, nullptr, nullptr, nullptr); | ||||||
|  |  | ||||||
|         onPollCallback(); |         onPollCallback(); | ||||||
| @@ -191,7 +209,7 @@ namespace ix | |||||||
|     { |     { | ||||||
| #ifdef __APPLE__ | #ifdef __APPLE__ | ||||||
|         wakeUpFromPollApple(); |         wakeUpFromPollApple(); | ||||||
| #else | #elif defined(__linux__) | ||||||
|         wakeUpFromPollLinux(); |         wakeUpFromPollLinux(); | ||||||
| #endif | #endif | ||||||
|     } |     } | ||||||
| @@ -202,7 +220,7 @@ namespace ix | |||||||
|     { |     { | ||||||
|         std::lock_guard<std::mutex> lock(_socketMutex); |         std::lock_guard<std::mutex> lock(_socketMutex); | ||||||
|  |  | ||||||
| #ifndef __APPLE__ | #ifdef __linux__ | ||||||
|         if (_eventfd == -1) |         if (_eventfd == -1) | ||||||
|         { |         { | ||||||
|             return false; // impossible to use this socket if eventfd is broken |             return false; // impossible to use this socket if eventfd is broken | ||||||
| @@ -219,7 +237,7 @@ namespace ix | |||||||
|  |  | ||||||
|         if (_sockfd == -1) return; |         if (_sockfd == -1) return; | ||||||
|  |  | ||||||
|         ::close(_sockfd); |         closeSocket(_sockfd); | ||||||
|         _sockfd = -1; |         _sockfd = -1; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -245,7 +263,36 @@ namespace ix | |||||||
|         flags = MSG_NOSIGNAL; |         flags = MSG_NOSIGNAL; | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|         return (int) ::recv(_sockfd, buffer, length, flags); |         return (int) ::recv(_sockfd, (char*) buffer, length, flags); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     int Socket::getErrno() const | ||||||
|  |     { | ||||||
|  | #ifdef _WIN32 | ||||||
|  |         return WSAGetLastError(); | ||||||
|  | #else | ||||||
|  |         return errno; | ||||||
|  | #endif | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     void Socket::closeSocket(int fd) | ||||||
|  |     { | ||||||
|  | #ifdef _WIN32 | ||||||
|  | 	closesocket(fd); | ||||||
|  | #else | ||||||
|  |         ::close(fd); | ||||||
|  | #endif | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // FIXME: need finalize | ||||||
|  |     bool Socket::init() | ||||||
|  |     { | ||||||
|  | #ifdef _WIN32 | ||||||
|  |         INT rc; | ||||||
|  |         WSADATA wsaData; | ||||||
|  |          | ||||||
|  |         rc = WSAStartup(MAKEWORD(2, 2), &wsaData); | ||||||
|  |         return rc != 0; | ||||||
|  | #endif | ||||||
|  |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -11,6 +11,8 @@ | |||||||
| #include <mutex> | #include <mutex> | ||||||
| #include <atomic> | #include <atomic> | ||||||
|  |  | ||||||
|  | struct addrinfo; | ||||||
|  |  | ||||||
| namespace ix  | namespace ix  | ||||||
| { | { | ||||||
|     class Socket { |     class Socket { | ||||||
| @@ -20,9 +22,11 @@ namespace ix | |||||||
|         Socket(); |         Socket(); | ||||||
|         virtual ~Socket(); |         virtual ~Socket(); | ||||||
|  |  | ||||||
|         static int hostname_connect(const std::string& hostname, | 	static bool init(); | ||||||
|                                     int port, |  | ||||||
|                                     std::string& errMsg); |         int hostname_connect(const std::string& hostname, | ||||||
|  |                              int port, | ||||||
|  |                              std::string& errMsg); | ||||||
|         void configure(); |         void configure(); | ||||||
|  |  | ||||||
|         virtual void poll(const OnPollCallback& onPollCallback); |         virtual void poll(const OnPollCallback& onPollCallback); | ||||||
| @@ -38,13 +42,22 @@ namespace ix | |||||||
|         virtual int send(const std::string& buffer); |         virtual int send(const std::string& buffer); | ||||||
|         virtual int recv(void* buffer, size_t length); |         virtual int recv(void* buffer, size_t length); | ||||||
|  |  | ||||||
|  |         int getErrno() const; | ||||||
|  |  | ||||||
|     protected: |     protected: | ||||||
|         void wakeUpFromPollApple(); |         void wakeUpFromPollApple(); | ||||||
|         void wakeUpFromPollLinux(); |         void wakeUpFromPollLinux(); | ||||||
|  |  | ||||||
|  |         void closeSocket(int fd); | ||||||
|  |  | ||||||
|         std::atomic<int> _sockfd; |         std::atomic<int> _sockfd; | ||||||
|         int _eventfd; |         int _eventfd; | ||||||
|         std::mutex _socketMutex; |         std::mutex _socketMutex; | ||||||
|  |  | ||||||
|  |     private: | ||||||
|  |         bool connectToAddress(const struct addrinfo *address,  | ||||||
|  |                               int& sockfd, | ||||||
|  |                               std::string& errMsg); | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -19,9 +19,9 @@ | |||||||
| # endif | # endif | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| #include <unistd.h> | // #include <unistd.h> | ||||||
| #include <errno.h> |  | ||||||
| #include <string.h> | #include <string.h> | ||||||
|  | #include <stdlib.h> | ||||||
|  |  | ||||||
| #include <cstdlib> | #include <cstdlib> | ||||||
| #include <vector> | #include <vector> | ||||||
| @@ -273,12 +273,12 @@ namespace ix { | |||||||
|                 { |                 { | ||||||
|                     int N = (int) _rxbuf.size(); |                     int N = (int) _rxbuf.size(); | ||||||
|  |  | ||||||
|                     ssize_t ret; |                     int ret; | ||||||
|                     _rxbuf.resize(N + 1500); |                     _rxbuf.resize(N + 1500); | ||||||
|                     ret = _socket->recv((char*)&_rxbuf[0] + N, 1500); |                     ret = _socket->recv((char*)&_rxbuf[0] + N, 1500); | ||||||
|  |  | ||||||
|                     if (ret < 0 && (errno == EWOULDBLOCK ||  |                     if (ret < 0 && (_socket->getErrno() == EWOULDBLOCK ||  | ||||||
|                                     errno == EAGAIN)) { |                                     _socket->getErrno() == EAGAIN)) { | ||||||
|                         _rxbuf.resize(N); |                         _rxbuf.resize(N); | ||||||
|                         break; |                         break; | ||||||
|                     } |                     } | ||||||
| @@ -575,8 +575,8 @@ namespace ix { | |||||||
|         { |         { | ||||||
|             int ret = _socket->send((char*)&_txbuf[0], _txbuf.size()); |             int ret = _socket->send((char*)&_txbuf[0], _txbuf.size()); | ||||||
|  |  | ||||||
|             if (ret < 0 && (errno == EWOULDBLOCK ||  |             if (ret < 0 && (_socket->getErrno() == EWOULDBLOCK ||  | ||||||
|                             errno == EAGAIN)) |                             _socket->getErrno() == EAGAIN)) | ||||||
|             { |             { | ||||||
|                 break; |                 break; | ||||||
|             } |             } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user