Make Socket noncopyable, without inheritance.

This commit is contained in:
Relintai 2022-02-09 23:48:12 +01:00
parent 0e6ad2d135
commit 94fd22eee9

View File

@ -16,7 +16,6 @@
#pragma once
#include <trantor/utils/NonCopyable.h>
#include "core/net/inet_address.h"
#include <trantor/utils/Logger.h>
#include <string>
@ -25,135 +24,133 @@
#endif
#include <fcntl.h>
namespace trantor
{
class Socket : NonCopyable
{
public:
static int createNonblockingSocketOrDie(int family)
{
namespace trantor {
class Socket {
protected:
// NonCopyable
Socket(const Socket &) = delete;
Socket &operator=(const Socket &) = delete;
// some uncopyable classes maybe support move constructor....
Socket(Socket &&) noexcept(true) = default;
Socket &operator=(Socket &&) noexcept(true) = default;
public:
static int createNonblockingSocketOrDie(int family) {
#ifdef __linux__
int sock = ::socket(family,
SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC,
IPPROTO_TCP);
int sock = ::socket(family,
SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC,
IPPROTO_TCP);
#else
int sock = static_cast<int>(::socket(family, SOCK_STREAM, IPPROTO_TCP));
setNonBlockAndCloseOnExec(sock);
int sock = static_cast<int>(::socket(family, SOCK_STREAM, IPPROTO_TCP));
setNonBlockAndCloseOnExec(sock);
#endif
if (sock < 0)
{
LOG_SYSERR << "sockets::createNonblockingOrDie";
exit(1);
}
LOG_TRACE << "sock=" << sock;
return sock;
}
if (sock < 0) {
LOG_SYSERR << "sockets::createNonblockingOrDie";
exit(1);
}
LOG_TRACE << "sock=" << sock;
return sock;
}
static int getSocketError(int sockfd)
{
int optval;
socklen_t optlen = static_cast<socklen_t>(sizeof optval);
static int getSocketError(int sockfd) {
int optval;
socklen_t optlen = static_cast<socklen_t>(sizeof optval);
#ifdef _WIN32
if (::getsockopt(
sockfd, SOL_SOCKET, SO_ERROR, (char *)&optval, &optlen) < 0)
if (::getsockopt(
sockfd, SOL_SOCKET, SO_ERROR, (char *)&optval, &optlen) < 0)
#else
if (::getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &optval, &optlen) < 0)
if (::getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &optval, &optlen) < 0)
#endif
{
return errno;
}
else
{
return optval;
}
}
{
return errno;
} else {
return optval;
}
}
static int connect(int sockfd, const InetAddress &addr)
{
if (addr.isIpV6())
return ::connect(sockfd,
addr.getSockAddr(),
static_cast<socklen_t>(
sizeof(struct sockaddr_in6)));
else
return ::connect(sockfd,
addr.getSockAddr(),
static_cast<socklen_t>(
sizeof(struct sockaddr_in)));
}
static int connect(int sockfd, const InetAddress &addr) {
if (addr.isIpV6())
return ::connect(sockfd,
addr.getSockAddr(),
static_cast<socklen_t>(
sizeof(struct sockaddr_in6)));
else
return ::connect(sockfd,
addr.getSockAddr(),
static_cast<socklen_t>(
sizeof(struct sockaddr_in)));
}
static bool isSelfConnect(int sockfd);
static bool isSelfConnect(int sockfd);
explicit Socket(int sockfd) : sockFd_(sockfd)
{
}
~Socket();
/// abort if address in use
void bindAddress(const InetAddress &localaddr);
/// abort if address in use
void listen();
int accept(InetAddress *peeraddr);
void closeWrite();
int read(char *buffer, uint64_t len);
int fd()
{
return sockFd_;
}
static struct sockaddr_in6 getLocalAddr(int sockfd);
static struct sockaddr_in6 getPeerAddr(int sockfd);
explicit Socket(int sockfd) :
sockFd_(sockfd) {
}
~Socket();
/// abort if address in use
void bindAddress(const InetAddress &localaddr);
/// abort if address in use
void listen();
int accept(InetAddress *peeraddr);
void closeWrite();
int read(char *buffer, uint64_t len);
int fd() {
return sockFd_;
}
static struct sockaddr_in6 getLocalAddr(int sockfd);
static struct sockaddr_in6 getPeerAddr(int sockfd);
///
/// Enable/disable TCP_NODELAY (disable/enable Nagle's algorithm).
///
void setTcpNoDelay(bool on);
///
/// Enable/disable TCP_NODELAY (disable/enable Nagle's algorithm).
///
void setTcpNoDelay(bool on);
///
/// Enable/disable SO_REUSEADDR
///
void setReuseAddr(bool on);
///
/// Enable/disable SO_REUSEADDR
///
void setReuseAddr(bool on);
///
/// Enable/disable SO_REUSEPORT
///
void setReusePort(bool on);
///
/// Enable/disable SO_REUSEPORT
///
void setReusePort(bool on);
///
/// Enable/disable SO_KEEPALIVE
///
void setKeepAlive(bool on);
int getSocketError();
///
/// Enable/disable SO_KEEPALIVE
///
void setKeepAlive(bool on);
int getSocketError();
protected:
int sockFd_;
protected:
int sockFd_;
public:
// taken from muduo
static void setNonBlockAndCloseOnExec(int sockfd)
{
public:
// taken from muduo
static void setNonBlockAndCloseOnExec(int sockfd) {
#ifdef _WIN32
// TODO how to set FD_CLOEXEC on windows? is it necessary?
u_long arg = 1;
auto ret = ioctlsocket(sockfd, (long)FIONBIO, &arg);
if (ret)
{
LOG_ERROR << "ioctlsocket error";
}
// TODO how to set FD_CLOEXEC on windows? is it necessary?
u_long arg = 1;
auto ret = ioctlsocket(sockfd, (long)FIONBIO, &arg);
if (ret) {
LOG_ERROR << "ioctlsocket error";
}
#else
// non-block
int flags = ::fcntl(sockfd, F_GETFL, 0);
flags |= O_NONBLOCK;
int ret = ::fcntl(sockfd, F_SETFL, flags);
// TODO check
// non-block
int flags = ::fcntl(sockfd, F_GETFL, 0);
flags |= O_NONBLOCK;
int ret = ::fcntl(sockfd, F_SETFL, flags);
// TODO check
// close-on-exec
flags = ::fcntl(sockfd, F_GETFD, 0);
flags |= FD_CLOEXEC;
ret = ::fcntl(sockfd, F_SETFD, flags);
// TODO check
// close-on-exec
flags = ::fcntl(sockfd, F_GETFD, 0);
flags |= FD_CLOEXEC;
ret = ::fcntl(sockfd, F_SETFD, flags);
// TODO check
(void)ret;
(void)ret;
#endif
}
}
};
} // namespace trantor
} // namespace trantor