Compare commits

...

7 Commits

Author SHA1 Message Date
a9ffa7da11 win code runs 2018-10-08 21:31:02 -07:00
44e5ab7f7d non blocking 2018-10-08 20:20:09 -07:00
280d1d7366 bring includes from rtm 2018-10-08 20:17:31 -07:00
37e899e872 compile errors 2018-10-08 18:42:56 -07:00
644d988c29 Revert "win port wip"
This reverts commit b68a4c26f2.
2018-10-08 18:27:32 -07:00
b68a4c26f2 win port wip 2018-10-08 18:24:40 -07:00
c3bf260330 windows port wip 2018-10-08 18:01:16 -07:00
4 changed files with 102 additions and 40 deletions

View File

@ -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;
} }

View File

@ -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
}
} }

View File

@ -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);
}; };
} }

View File

@ -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;
} }