Socket.cc revision 8bdf4aaf
1efbfdb0cSShuo Chen#include "Socket.h" 2efbfdb0cSShuo Chen#include "InetAddress.h" 3efbfdb0cSShuo Chen 4efbfdb0cSShuo Chen#include <assert.h> 5efbfdb0cSShuo Chen#include <unistd.h> 6efbfdb0cSShuo Chen#include <netinet/in.h> 7a52ee0fdSShuo Chen#include <netinet/tcp.h> 8efbfdb0cSShuo Chen#include <sys/socket.h> 9efbfdb0cSShuo Chen 10efbfdb0cSShuo ChenSocket::Socket(int sockfd) 11efbfdb0cSShuo Chen : sockfd_(sockfd) 12efbfdb0cSShuo Chen{ 13efbfdb0cSShuo Chen assert(sockfd_ >= 0); 14efbfdb0cSShuo Chen} 15efbfdb0cSShuo Chen 16efbfdb0cSShuo ChenSocket::~Socket() 17efbfdb0cSShuo Chen{ 18efbfdb0cSShuo Chen if (sockfd_ >= 0) 19efbfdb0cSShuo Chen { 20efbfdb0cSShuo Chen int ret = ::close(sockfd_); 21efbfdb0cSShuo Chen assert(ret == 0); (void)ret; 22efbfdb0cSShuo Chen } 23efbfdb0cSShuo Chen} 24efbfdb0cSShuo Chen 25efbfdb0cSShuo Chenvoid Socket::bindOrDie(const InetAddress& addr) 26efbfdb0cSShuo Chen{ 2724ca08a8SShuo Chen int ret = ::bind(sockfd_, addr.get_sockaddr(), addr.length()); 28efbfdb0cSShuo Chen if (ret) 29efbfdb0cSShuo Chen { 30efbfdb0cSShuo Chen perror("Socket::bindOrDie"); 31efbfdb0cSShuo Chen abort(); 32efbfdb0cSShuo Chen } 33efbfdb0cSShuo Chen} 34efbfdb0cSShuo Chen 35efbfdb0cSShuo Chenvoid Socket::listenOrDie() 36efbfdb0cSShuo Chen{ 37efbfdb0cSShuo Chen int ret = ::listen(sockfd_, SOMAXCONN); 38efbfdb0cSShuo Chen if (ret) 39efbfdb0cSShuo Chen { 40efbfdb0cSShuo Chen perror("Socket::listen"); 41efbfdb0cSShuo Chen abort(); 42efbfdb0cSShuo Chen } 43efbfdb0cSShuo Chen} 44efbfdb0cSShuo Chen 458f04b50cSShuo Chenint Socket::connect(const InetAddress& addr) 468f04b50cSShuo Chen{ 4724ca08a8SShuo Chen return ::connect(sockfd_, addr.get_sockaddr(), addr.length()); 488f04b50cSShuo Chen} 498f04b50cSShuo Chen 50a52ee0fdSShuo Chenvoid Socket::shutdownWrite() 51a52ee0fdSShuo Chen{ 52a52ee0fdSShuo Chen if (::shutdown(sockfd_, SHUT_WR) < 0) 53a52ee0fdSShuo Chen { 54a52ee0fdSShuo Chen perror("Socket::shutdownWrite"); 55a52ee0fdSShuo Chen } 56a52ee0fdSShuo Chen} 57a52ee0fdSShuo Chen 588f04b50cSShuo Chenvoid Socket::setReuseAddr(bool on) 598f04b50cSShuo Chen{ 608f04b50cSShuo Chen int optval = on ? 1 : 0; 61a52ee0fdSShuo Chen if (::setsockopt(sockfd_, SOL_SOCKET, SO_REUSEADDR, 62a52ee0fdSShuo Chen &optval, sizeof optval) < 0) 63a52ee0fdSShuo Chen { 64a52ee0fdSShuo Chen perror("Socket::setReuseAddr"); 65a52ee0fdSShuo Chen } 66a52ee0fdSShuo Chen} 67a52ee0fdSShuo Chen 68a52ee0fdSShuo Chenvoid Socket::setTcpNoDelay(bool on) 69a52ee0fdSShuo Chen{ 70a52ee0fdSShuo Chen int optval = on ? 1 : 0; 71a52ee0fdSShuo Chen if (::setsockopt(sockfd_, IPPROTO_TCP, TCP_NODELAY, 72a52ee0fdSShuo Chen &optval, static_cast<socklen_t>(sizeof optval)) < 0) 73a52ee0fdSShuo Chen { 74a52ee0fdSShuo Chen perror("Socket::setTcpNoDelay"); 75a52ee0fdSShuo Chen } 768f04b50cSShuo Chen} 778f04b50cSShuo Chen 78f41285cfSShuo ChenInetAddress Socket::getLocalAddr() const 79f41285cfSShuo Chen{ 8024ca08a8SShuo Chen struct sockaddr localaddr; 8124ca08a8SShuo Chen socklen_t addrlen = sizeof localaddr; 8224ca08a8SShuo Chen if (::getsockname(sockfd_, &localaddr, &addrlen) < 0) 83f41285cfSShuo Chen { 84f41285cfSShuo Chen perror("Socket::getLocalAddr"); 85f41285cfSShuo Chen } 86f41285cfSShuo Chen return InetAddress(localaddr); 87f41285cfSShuo Chen} 88f41285cfSShuo Chen 89f41285cfSShuo ChenInetAddress Socket::getPeerAddr() const 90f41285cfSShuo Chen{ 9124ca08a8SShuo Chen struct sockaddr peeraddr; 9224ca08a8SShuo Chen socklen_t addrlen = sizeof peeraddr; 9324ca08a8SShuo Chen if (::getpeername(sockfd_, &peeraddr, &addrlen) < 0) 94f41285cfSShuo Chen { 95f41285cfSShuo Chen perror("Socket::getPeerAddr"); 96f41285cfSShuo Chen } 97f41285cfSShuo Chen return InetAddress(peeraddr); 98f41285cfSShuo Chen} 99f41285cfSShuo Chen 1008bdf4aafSShuo Chenint Socket::recv(void* buf, int len) 101efbfdb0cSShuo Chen{ 1028bdf4aafSShuo Chen return TEMP_FAILURE_RETRY(::recv(sockfd_, buf, len, 0)); 103aafef3ccSShuo Chen} 104aafef3ccSShuo Chen 1058bdf4aafSShuo Chenint Socket::send(const void* buf, int len) 106aafef3ccSShuo Chen{ 1078bdf4aafSShuo Chen return TEMP_FAILURE_RETRY(::send(sockfd_, buf, len, 0)); 108aafef3ccSShuo Chen} 109aafef3ccSShuo Chen 11024ca08a8SShuo ChenSocket Socket::createTCP(sa_family_t family) 111aafef3ccSShuo Chen{ 11224ca08a8SShuo Chen int sockfd = ::socket(family, SOCK_STREAM | SOCK_CLOEXEC, IPPROTO_TCP); 113aafef3ccSShuo Chen assert(sockfd >= 0); 114aafef3ccSShuo Chen return Socket(sockfd); 115aafef3ccSShuo Chen} 116aafef3ccSShuo Chen 11724ca08a8SShuo ChenSocket Socket::createUDP(sa_family_t family) 118aafef3ccSShuo Chen{ 11924ca08a8SShuo Chen int sockfd = ::socket(family, SOCK_DGRAM | SOCK_CLOEXEC, IPPROTO_UDP); 120efbfdb0cSShuo Chen assert(sockfd >= 0); 121efbfdb0cSShuo Chen return Socket(sockfd); 122efbfdb0cSShuo Chen} 123efbfdb0cSShuo Chen 124