1#include "Socket.h" 2#include "InetAddress.h" 3 4#include <assert.h> 5#include <unistd.h> 6#include <netinet/in.h> 7#include <netinet/tcp.h> 8#include <sys/socket.h> 9 10Socket::Socket(int sockfd) 11 : sockfd_(sockfd) 12{ 13 assert(sockfd_ >= 0); 14} 15 16Socket::~Socket() 17{ 18 if (sockfd_ >= 0) 19 { 20 int ret = ::close(sockfd_); 21 assert(ret == 0); (void)ret; 22 } 23} 24 25void Socket::bindOrDie(const InetAddress& addr) 26{ 27 int ret = ::bind(sockfd_, addr.get_sockaddr(), addr.length()); 28 if (ret) 29 { 30 perror("Socket::bindOrDie"); 31 abort(); 32 } 33} 34 35void Socket::listenOrDie() 36{ 37 int ret = ::listen(sockfd_, SOMAXCONN); 38 if (ret) 39 { 40 perror("Socket::listen"); 41 abort(); 42 } 43} 44 45int Socket::connect(const InetAddress& addr) 46{ 47 return ::connect(sockfd_, addr.get_sockaddr(), addr.length()); 48} 49 50void Socket::shutdownWrite() 51{ 52 if (::shutdown(sockfd_, SHUT_WR) < 0) 53 { 54 perror("Socket::shutdownWrite"); 55 } 56} 57 58void Socket::setReuseAddr(bool on) 59{ 60 int optval = on ? 1 : 0; 61 if (::setsockopt(sockfd_, SOL_SOCKET, SO_REUSEADDR, 62 &optval, sizeof optval) < 0) 63 { 64 perror("Socket::setReuseAddr"); 65 } 66} 67 68void Socket::setTcpNoDelay(bool on) 69{ 70 int optval = on ? 1 : 0; 71 if (::setsockopt(sockfd_, IPPROTO_TCP, TCP_NODELAY, 72 &optval, static_cast<socklen_t>(sizeof optval)) < 0) 73 { 74 perror("Socket::setTcpNoDelay"); 75 } 76} 77 78InetAddress Socket::getLocalAddr() const 79{ 80 struct sockaddr_storage localaddr; 81 socklen_t addrlen = sizeof localaddr; 82 struct sockaddr* addr = reinterpret_cast<struct sockaddr*>(&localaddr); 83 if (::getsockname(sockfd_, addr, &addrlen) < 0) 84 { 85 perror("Socket::getLocalAddr"); 86 } 87 return InetAddress(*addr); 88} 89 90InetAddress Socket::getPeerAddr() const 91{ 92 struct sockaddr_storage peeraddr; 93 socklen_t addrlen = sizeof peeraddr; 94 struct sockaddr* addr = reinterpret_cast<struct sockaddr*>(&peeraddr); 95 if (::getpeername(sockfd_, addr, &addrlen) < 0) 96 { 97 perror("Socket::getPeerAddr"); 98 } 99 return InetAddress(*addr); 100} 101 102int Socket::recv(void* buf, int len) 103{ 104#ifdef TEMP_FAILURE_RETRY 105 return TEMP_FAILURE_RETRY(::recv(sockfd_, buf, len, 0)); 106#else 107 return ::recv(sockfd_, buf, len, 0); 108#endif 109} 110 111int Socket::send(const void* buf, int len) 112{ 113#ifdef TEMP_FAILURE_RETRY 114 return TEMP_FAILURE_RETRY(::send(sockfd_, buf, len, 0)); 115#else 116 return ::send(sockfd_, buf, len, 0); 117#endif 118} 119 120Socket Socket::createTCP(sa_family_t family) 121{ 122 int sockfd = ::socket(family, SOCK_STREAM | SOCK_CLOEXEC, IPPROTO_TCP); 123 assert(sockfd >= 0); 124 return Socket(sockfd); 125} 126 127Socket Socket::createUDP(sa_family_t family) 128{ 129 int sockfd = ::socket(family, SOCK_DGRAM | SOCK_CLOEXEC, IPPROTO_UDP); 130 assert(sockfd >= 0); 131 return Socket(sockfd); 132} 133 134