20 #define BUF_CAST(buf) ((char*)buf)
25 #include <arpa/inet.h>
26 #include <netinet/tcp.h>
27 #include <netinet/in.h>
28 #include <sys/socket.h>
29 #define BUF_CAST(buf) ((void*)buf)
34 using std::make_unique;
43 TCPSocket* TCPSocket::createServerSocket(
const string& ip,
const unsigned int port,
const int backlog) {
45 auto socket = make_unique<TCPSocket>();
47 socket->descriptor = ::socket(ipVersion ==
IPV6?PF_INET6:PF_INET, SOCK_STREAM, IPPROTO_TCP);
48 if (socket->descriptor == -1) {
51 #if defined(__APPLE__)
53 if (setsockopt(socket->descriptor, SOL_SOCKET, SO_NOSIGPIPE, (
void*)&flag,
sizeof(flag)) == -1) {
61 socket->setNonBlocked();
67 if (listen(socket->descriptor, backlog) == -1) {
76 return socket.release();
88 if (setsockopt(
descriptor, IPPROTO_TCP, TCP_NODELAY, (
const char*)&flag,
sizeof(flag)) == -1) {
90 if (setsockopt(
descriptor, IPPROTO_TCP, TCP_NODELAY, (
void*)&flag,
sizeof(flag)) == -1) {
101 descriptor = ::socket(ipVersion ==
IPV6?PF_INET6:PF_INET, SOCK_STREAM, IPPROTO_TCP);
105 #if defined(__APPLE__)
107 if (setsockopt(
descriptor, SOL_SOCKET, SO_NOSIGPIPE, (
void*)&flag,
sizeof(flag)) == -1) {
113 socklen_t sinLen = 0;
116 sockaddr_in6 sinIPV6;
120 sinLen =
sizeof(sinIPV4);
121 memset(&sinIPV4, 0, sinLen);
122 sinIPV4.sin_family = AF_INET;
123 sinIPV4.sin_port = htons(
port);
124 sinIPV4.sin_addr.s_addr = inet_addr(
ip.c_str());
130 sinLen =
sizeof(sinIPV6);
131 memset(&sinIPV6, 0, sinLen);
132 sinIPV6.sin6_family = AF_INET6;
133 sinIPV6.sin6_port = htons(
port);
134 inet_pton(AF_INET6,
ip.c_str(), &sinIPV6.sin6_addr);
155 struct sockaddr_in _sin;
156 socklen_t _sinSize =
sizeof(_sin);
160 if (_descriptor == -1) {
162 if (errno == EAGAIN ||
163 errno == EWOULDBLOCK) {
171 _socket->
ip = inet_ntoa(_sin.sin_addr);
172 _socket->
port = ntohs(_sin.sin_port);
182 if (bytesRead == -1) {
183 throw NetworkIOException(
"Error while reading from socket: " +
string(strerror(errno)));
185 if (bytesRead == 0) {
189 return (
size_t)bytesRead;
193 #if defined(__APPLE__) || defined(_WIN32)
198 if (bytesWritten == -1) {
199 if (errno == ECONNRESET || errno == EPIPE) {
202 throw NetworkIOException(
"Error while writing to socket: " +
string(strerror(errno)));
206 return (
size_t)bytesWritten;
Base exception class for network IO exceptions.
Network socket closed exception.
Base class of network sockets.
static IpVersion determineIpVersion(const string &ip)
Determine IP version.
void setNonBlocked()
sets the socket non blocked
Class representing a TCP socket.
virtual size_t read(void *buf, const size_t bytes)
Reads up to "bytes" bytes from socket.
virtual size_t write(void *buf, const size_t bytes)
Writes up to "bytes" bytes to socket.
virtual bool accept(TCPSocket *_socket)
Accepts a socket from a server socket.
virtual ~TCPSocket()
Destructor.
void setTCPNoDelay()
Disables nagle's algorithm.
virtual void connect(const string &ip, const unsigned int port)
Connects a socket to given remote IP and port.