12 #include <netinet/in.h>
31 terr(
"socket: Invalid socket_type! Using TCP.");
43 if (setsockopt(
m_fd, SOL_SOCKET, SO_NOSIGPIPE, (
char *)&on,
sizeof(on))) {
45 "setsockopt SO_NOSIGPIPE failed: " + std::string(std::strerror(errno)), errno);
49 if (fcntl(
m_fd, F_SETFL, fcntl(
m_fd, F_GETFL, 0) | O_NONBLOCK)) {
54 struct sockaddr_un addr;
55 bzero(&addr,
sizeof(
struct sockaddr_un));
56 addr.sun_family = AF_UNIX;
57 std::strcpy(addr.sun_path, path.c_str());
58 unlink(addr.sun_path);
60 if (::
bind(
m_fd, (
struct sockaddr *)&addr,
sizeof(addr.sun_family) + path.length())) {
64 if (::
bind(
m_fd, (
struct sockaddr *)&addr, SUN_LEN(&addr))) {
68 if (chmod(path.c_str(), S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)) {
80 bind(port, ip,
false );
87 bind(port, ip,
true );
93 m_fd =
::socket(AF_INET, udp ? SOCK_DGRAM : SOCK_STREAM, 0);
97 if (setsockopt(
m_fd, SOL_SOCKET, SO_REUSEADDR, (
char *)&on,
sizeof(on))) {
99 "setsockopt SO_REUSEADDR failed: " + std::string(std::strerror(errno)), errno);
102 if (setsockopt(
m_fd, SOL_SOCKET, SO_NOSIGPIPE, (
char *)&on,
sizeof(on))) {
104 "setsockopt SO_NOSIGPIPE failed: " + std::string(std::strerror(errno)), errno);
108 if (fcntl(
m_fd, F_SETFL, fcntl(
m_fd, F_GETFL, 0) | O_NONBLOCK)) {
121 m_addr = std::make_shared<struct sockaddr_in>();
123 bzero(
m_addr.get(),
sizeof(
struct sockaddr_in));
124 m_addr->sin_family = AF_INET;
126 if (inet_pton(AF_INET, ip.c_str(), &(
m_addr->sin_addr)) < 1) {
127 terr(
"socket: Invalid ip " << ip <<
"! Binding to 0.0.0.0!" << std::endl);
128 m_addr->sin_addr.s_addr = INADDR_ANY;
131 m_addr->sin_addr.s_addr = INADDR_ANY;
133 m_addr->sin_port = htons(port);
137 struct sockaddr_in addr;
138 bzero(&addr,
sizeof(
struct sockaddr_in));
139 socklen_t len =
sizeof(
addr);
140 int client =
::accept(
m_fd, (
struct sockaddr *)&addr, &len);
154 if (setsockopt(
m_fd, SOL_SOCKET, SO_NOSIGPIPE, (
char *)&on,
sizeof(on))) {
156 "setsockopt SO_NOSIGPIPE failed: " + std::string(std::strerror(errno)), errno);
159 struct sockaddr_un addr;
160 bzero(&addr,
sizeof(
struct sockaddr_un));
161 addr.sun_family = AF_UNIX;
162 std::strcpy(addr.sun_path, path.c_str());
165 if (::
connect(
m_fd, (
struct sockaddr *)&addr,
sizeof(addr.sun_family) + path.length())) {
170 addr.sun_len = SUN_LEN(&addr);
171 if (::
connect(
m_fd, (
struct sockaddr *)&addr, SUN_LEN(&addr))) {
178 if (fcntl(
m_fd, F_SETFL, fcntl(
m_fd, F_GETFL, 0) | O_NONBLOCK)) {
186 struct hostent *remote = gethostbyname(host.c_str());
187 if (
nullptr == remote) {
196 if (setsockopt(
m_fd, SOL_SOCKET, SO_NOSIGPIPE, (
char *)&on,
sizeof(on))) {
198 "setsockopt SO_NOSIGPIPE failed: " + std::string(std::strerror(errno)), errno);
201 struct sockaddr_in addr;
202 bzero(&addr,
sizeof(
struct sockaddr_in));
203 addr.sin_family = AF_INET;
204 std::memcpy(&addr.sin_addr, remote->h_addr_list[0], remote->h_length);
205 addr.sin_port = htons(port);
206 if (::
connect(
m_fd, (
struct sockaddr *)&addr,
sizeof(addr))) {
211 if (fcntl(
m_fd, F_SETFL, fcntl(
m_fd, F_GETFL, 0) | O_NONBLOCK)) {
225 std::streamsize
socket::write(
const char *data, std::size_t len,
int port, std::string ip) {
236 const sockaddr *
addr =
nullptr;
237 socklen_t addr_len = 0;
239 addr = (
const sockaddr *)
m_addr.get();
240 addr_len =
sizeof(*addr);
243 if (bytes < 0 && errno != EAGAIN) {
245 s <<
"error writing to client file descriptor " <<
m_fd <<
": " << std::strerror(errno);
252 sockaddr *
addr =
nullptr;
253 socklen_t addr_len = 0;
255 addr = (sockaddr *)
m_addr.get();
256 addr_len =
sizeof(*addr);
259 if (bytes < 0 && errno != EAGAIN) {
261 s <<
"error reading from client file descriptor " <<
m_fd <<
": " << std::strerror(errno);
263 }
else if (bytes == 0) {
265 s <<
"client " <<
m_fd <<
" disconnected";
void bind(int port, std::string ip="")
Error on sendto sys call.
std::streamsize write(const char *data, std::size_t len, int port=-1, std::string ip="")
Error on chmod sys call (domain sockets)
Error on setsockopt sys call.
std::shared_ptr< struct sockaddr_in > addr()
std::streamsize read(char *data, std::size_t len)
Base class for socket and term.
socket accept()
Accept new client connections.
Error when calling listen on a UDP socket.
void shutdown()
Call shutdown on the fd.
Error on setsockopt sys call.
Error on listen sys call.
Error on connect sys call.
Error when reading from a disconnected socket.
Error on accept sys call.
void init_sockaddr(int port, std::string ip="")
Error on recvfrom sys call.
void connect(std::string path)
Error on socket sys call.
void listen(std::string path, int queue_size=128)
std::shared_ptr< struct sockaddr_in > m_addr
Error when trying to connect to a host that can't be resolved.