blob: 80eca70fcfb892f061b6319c7f83b9872331e15f [file] [log] [blame]
#include "aos/common/network/socket.h"
#include <errno.h>
#include <string.h>
#include <sys/socket.h>
#include <chrono>
#include "aos/common/byteorder.h"
#include "aos/common/logging/logging.h"
namespace aos {
namespace network {
namespace chrono = ::std::chrono;
int Socket::Connect(NetworkPort port, const char *address, int type) {
last_ret_ = 0;
if ((socket_ = socket(AF_INET, type, 0)) < 0) {
PLOG(ERROR, "failed to create socket");
return last_ret_ = 1;
}
memset(&addr_, 0, sizeof(addr_));
addr_.in.sin_family = AF_INET;
addr_.in.sin_port = hton<uint16_t>(static_cast<uint16_t>(port));
#ifndef __VXWORKS__
const int failure_return = 0;
#else
const int failure_return = -1;
#endif
if (inet_aton(address, &addr_.in.sin_addr) == failure_return) {
PLOG(ERROR, "invalid IP address '%s'", address);
return last_ret_ = -1;
}
return last_ret_ = 0;
}
Socket::Socket() : socket_(-1), last_ret_(2) {}
Socket::~Socket() {
close(socket_);
}
void Socket::Reset() {
if (socket_ != -1) {
close(socket_);
socket_ = -1;
}
last_ret_ = 0;
}
int Socket::Receive(void *buf, int length) {
const int ret = recv(socket_, static_cast<char *>(buf), length, 0);
last_ret_ = (ret == -1) ? -1 : 0;
return ret;
}
int Socket::Receive(void *buf, int length, chrono::microseconds timeout) {
timeval timeout_timeval;
timeout_timeval.tv_sec = chrono::duration_cast<chrono::seconds>(timeout).count();
timeout_timeval.tv_usec =
chrono::duration_cast<chrono::microseconds>(
timeout - chrono::seconds(timeout_timeval.tv_sec))
.count();
fd_set fds;
FD_ZERO(&fds);
FD_SET(socket_, &fds);
switch (select(FD_SETSIZE, &fds, NULL, NULL, &timeout_timeval)) {
case 1:
return Receive(buf, length);
case 0:
return last_ret_ = 0;
default:
if (errno == EINTR) {
return last_ret_ = 0;
}
PLOG(FATAL, "select(FD_SETSIZE, %p, NULL, NULL, %p) failed",
&fds, &timeout_timeval);
}
}
int Socket::Send(const void *buf, int length) {
const int ret = write(socket_,
static_cast<const char *>(buf), length);
last_ret_ = (ret == -1) ? -1 : 0;
return ret;
}
} // namespace network
} // namespace aos