13 #define close(fd) closesocket(fd)
20 #include <sys/socket.h>
21 #include <netinet/in.h>
22 #include <netinet/tcp.h>
23 #include <arpa/inet.h>
28 #define constrain(x, l, u) (x<l?l:(x>u?u:x))
38 sockaddr_in _remote_addr;
68 int rv = WSAPoll(&pfs, 1, 0);
69 if ((rv == -1 && WSAGetLastError() == WSAENETDOWN) || (rv > 0 && (pfs.revents & POLLNVAL) != 0)) {
70 #ifdef ETCP_ERROR_PRINT
71 printf(
"poll triggered stop, rv=%d: %s\n", rv, strerror(errno));
75 return (pfs.revents & POLLRDNORM) != 0 || (pfs.revents & POLLHUP) != 0;
82 int rv = ::poll(&pfs, 1, 0);
83 if (rv == -1 || (rv > 0 && (pfs.revents & POLLNVAL) != 0)) {
84 #ifdef ETCP_ERROR_PRINT
85 printf(
"poll triggered stop, rv=%d: %s\n", rv, strerror(errno));
89 return (pfs.revents & POLLIN) != 0 || (pfs.revents & POLLHUP) != 0;
95 bool connect(
const uint8_t *address, uint16_t port)
98 #ifdef ETCP_ERROR_PRINT
99 printf(
"connect triggered stop, _fd=%d\n", _fd);
103 _fd = ::socket(AF_INET,SOCK_STREAM,0);
107 memset(&_remote_addr, 0,
sizeof(_remote_addr));
108 _remote_addr.sin_family = AF_INET;
109 _remote_addr.sin_port = htons(port);
110 memcpy(&_remote_addr.sin_addr.s_addr, address, 4);
113 struct timeval read_timeout;
114 read_timeout.tv_sec = 0;
115 read_timeout.tv_usec = 2000000;
117 setsockopt(_fd, SOL_SOCKET, SO_RCVTIMEO, (
char*)&read_timeout,
sizeof read_timeout);
118 setsockopt(_fd, SOL_SOCKET, SO_SNDTIMEO, (
char*)&read_timeout,
sizeof read_timeout);
121 bool connected = ::connect(_fd, (
struct sockaddr *) &_remote_addr,
sizeof(_remote_addr)) == 0;
125 struct timeval read_timeout;
126 read_timeout.tv_sec = 0;
127 read_timeout.tv_usec = 1000;
128 setsockopt(_fd, SOL_SOCKET, SO_RCVTIMEO, (
char*)&read_timeout,
sizeof read_timeout);
129 read_timeout.tv_usec = 2000000;
130 setsockopt(_fd, SOL_SOCKET, SO_SNDTIMEO, (
char*)&read_timeout,
sizeof read_timeout);
139 bool prepare_connect(
const uint8_t *address, uint16_t port)
142 #ifdef ETCP_ERROR_PRINT
143 printf(
"prepare_connect triggered stop, _fd=%d\n", _fd);
147 _fd = ::socket(AF_INET,SOCK_STREAM,0);
151 memset(&_remote_addr, 0,
sizeof(_remote_addr));
152 _remote_addr.sin_family = AF_INET;
153 _remote_addr.sin_port = htons(port);
154 memcpy(&_remote_addr.sin_addr.s_addr, address, 4);
156 unsigned long ul = 1;
157 int flags = ioctlsocket(_fd, FIONBIO, (
unsigned long *)&ul);
158 if (flags != SOCKET_ERROR) ;
160 int flags = fcntl(_fd, F_GETFL, 0);
162 fcntl(_fd, F_SETFL, flags | O_NONBLOCK);
166 #ifdef ETCP_ERROR_PRINT
167 printf(
"prepare_connect triggered stop, _fd=%d: %s\n", _fd, strerror(errno));
177 int8_t connected = 0;
178 int status = ::connect(_fd, (
struct sockaddr *) &_remote_addr,
sizeof(_remote_addr));
181 int errno2 = WSAGetLastError();
182 if (errno2 == WSAEISCONN);
183 else if (errno2 == WSAEWOULDBLOCK || errno2 == WSAEINPROGRESS || errno2 == WSAEALREADY) {
187 if (errno == EISCONN);
188 else if (errno == EINPROGRESS || errno == EALREADY) {
193 #ifdef ETCP_ERROR_PRINT
195 printf(
"try_connect triggered stop, _fd=%d: %d\n", _fd, errno2);
197 printf(
"try_connect triggered stop, _fd=%d: %d %s\n", _fd, errno, strerror(errno));
207 unsigned long ul = 0;
208 int flags = ioctlsocket(_fd, FIONBIO, (
unsigned long *)&ul);
211 int flags = fcntl(_fd, F_GETFL, 0);
213 fcntl(_fd, F_SETFL, flags & ~O_NONBLOCK);
219 struct timeval read_timeout;
220 read_timeout.tv_sec = 0;
221 read_timeout.tv_usec = 1000;
222 setsockopt(_fd, SOL_SOCKET, SO_RCVTIMEO, (
char*)&read_timeout,
sizeof read_timeout);
223 read_timeout.tv_usec = 2000000;
224 setsockopt(_fd, SOL_SOCKET, SO_SNDTIMEO, (
char*)&read_timeout,
sizeof read_timeout);
233 void set_nodelay(
bool nodelay)
237 setsockopt(_fd, IPPROTO_TCP, TCP_NODELAY, (
char*)&flag,
sizeof flag);
246 int read(uint8_t *buffer,
int buffer_size)
251 int r = ::recv(_fd, (
char*)buffer, buffer_size, 0);
254 int errno2 = WSAGetLastError();
255 if (errno2 == WSAEWOULDBLOCK) {
258 #ifdef ETCP_ERROR_PRINT
259 printf(
"read triggered stop, r=%d: %d\n", r, errno2);
262 if (errno == EAGAIN) {
265 #ifdef ETCP_ERROR_PRINT
266 printf(
"read triggered stop, r=%d: %s\n", r, strerror(errno));
274 int write(
const uint8_t *buffer,
int size)
279 #if defined(_WIN32) || defined(__ZEPHYR__)
280 int w =
::send(_fd, (
char*)buffer, size, 0);
282 int w =
::send(_fd, (
char*)buffer, size, MSG_NOSIGNAL);
285 #ifdef ETCP_ERROR_PRINT
287 int errno2 = WSAGetLastError();
288 printf(
"write triggered stop, w=%d: %d\n", w, errno2);
290 if (errno != EPIPE) {
291 printf(
"write triggered stop, w=%d: %s\n", w, strerror(errno));
306 ::shutdown(_fd, SHUT_RDWR);
322 bool operator==(
const bool value)
324 return bool() == value;
326 bool operator!=(
const bool value)
328 return bool() != value;
332 return _fd == rhs._fd && _fd != -1 && rhs._fd != -1;
336 return !this->operator==(rhs);
338 uint8_t getSocketNumber()
343 int print(
const char *msg)
345 return write((
const uint8_t*) msg, strlen(msg));
354 sockaddr_in _localaddr, _remote_sender_addr;
359 _port = listening_port;
363 #ifdef ETCP_DEBUG_PRINT
364 printf(
"destructor triggered stop, _fd=%d\n", _fd);
371 socklen_t len =
sizeof(_remote_sender_addr);
372 memset(&_remote_sender_addr, 0, len);
373 int connected_fd = _fd == -1 ? -1 : ::accept(_fd, (
struct sockaddr *) &_remote_sender_addr, &len);
374 if (connected_fd != -1) {
377 struct timeval read_timeout;
378 read_timeout.tv_sec = 0;
379 read_timeout.tv_usec = 1000;
380 setsockopt(connected_fd, SOL_SOCKET, SO_RCVTIMEO, (
char*)&read_timeout,
sizeof read_timeout);
381 read_timeout.tv_usec = 2000000;
382 setsockopt(connected_fd, SOL_SOCKET, SO_SNDTIMEO, (
char*)&read_timeout,
sizeof read_timeout);
386 setsockopt(connected_fd, IPPROTO_TCP, TCP_NODELAY, (
char*)&flag,
sizeof flag);
400 _fd=socket(AF_INET,SOCK_STREAM,0);
402 #ifdef ETCP_ERROR_PRINT
403 printf(
"failure creating socket: %s\n", strerror(errno));
409 setsockopt(_fd, SOL_SOCKET, SO_REUSEADDR, (
char*)&yes,
sizeof(yes));
412 memset(&_localaddr, 0,
sizeof(_localaddr));
413 _localaddr.sin_family = AF_INET;
414 _localaddr.sin_port = htons(_port);
415 _localaddr.sin_addr.s_addr = htonl(INADDR_ANY);
416 if (bind(_fd,(
struct sockaddr *) &_localaddr,
sizeof(_localaddr))==-1) {
417 #ifdef ETCP_ERROR_PRINT
418 printf(
"bind failed: %s\n", strerror(errno));
424 if (listen(_fd, 5) == -1) {
425 #ifdef ETCP_ERROR_PRINT
426 printf(
"listen failed: %s\n", strerror(errno));
433 unsigned long ul = 1;
434 int flags = ioctlsocket(_fd, FIONBIO, (
unsigned long *)&ul);
435 if (flags != NO_ERROR) {
436 #ifdef ETCP_ERROR_PRINT
437 printf(
"ioctlsocket FIONBIO failed.");
441 int flags = fcntl(_fd, F_GETFL, 0);
443 fcntl(_fd, F_SETFL, flags | O_NONBLOCK);
446 memset(&_remote_sender_addr, 0,
sizeof(_remote_sender_addr));