mirror of
https://github.com/Relintai/rcpp_framework.git
synced 2024-11-10 00:52:11 +01:00
Make Socket noncopyable, without inheritance.
This commit is contained in:
parent
0e6ad2d135
commit
94fd22eee9
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user