10e478f5aSAxel Dörfler /* 20e478f5aSAxel Dörfler * Copyright 2011, Axel Dörfler, axeld@pinc-software.de. 3c9dd7d0dSRene Gollent * Copyright 2016, Rene Gollent, rene@gollent.com. 40e478f5aSAxel Dörfler * Distributed under the terms of the MIT License. 50e478f5aSAxel Dörfler */ 60e478f5aSAxel Dörfler 70e478f5aSAxel Dörfler 80e478f5aSAxel Dörfler #include <Socket.h> 90e478f5aSAxel Dörfler 100dc3ab4fSAugustin Cavalier #include <errno.h> 110e478f5aSAxel Dörfler 12*a31d07a2SAugustin Cavalier 130e478f5aSAxel Dörfler //#define TRACE_SOCKET 140e478f5aSAxel Dörfler #ifdef TRACE_SOCKET 150e478f5aSAxel Dörfler # define TRACE(x...) printf(x) 160e478f5aSAxel Dörfler #else 170e478f5aSAxel Dörfler # define TRACE(x...) ; 180e478f5aSAxel Dörfler #endif 190e478f5aSAxel Dörfler 200e478f5aSAxel Dörfler 210e478f5aSAxel Dörfler BSocket::BSocket() 220e478f5aSAxel Dörfler { 230e478f5aSAxel Dörfler } 240e478f5aSAxel Dörfler 250e478f5aSAxel Dörfler 260e478f5aSAxel Dörfler BSocket::BSocket(const BNetworkAddress& peer, bigtime_t timeout) 270e478f5aSAxel Dörfler { 280e478f5aSAxel Dörfler Connect(peer, timeout); 290e478f5aSAxel Dörfler } 300e478f5aSAxel Dörfler 310e478f5aSAxel Dörfler 320e478f5aSAxel Dörfler BSocket::BSocket(const BSocket& other) 330e478f5aSAxel Dörfler : 340e478f5aSAxel Dörfler BAbstractSocket(other) 350e478f5aSAxel Dörfler { 360e478f5aSAxel Dörfler } 370e478f5aSAxel Dörfler 380e478f5aSAxel Dörfler 390e478f5aSAxel Dörfler BSocket::~BSocket() 400e478f5aSAxel Dörfler { 410e478f5aSAxel Dörfler } 420e478f5aSAxel Dörfler 430e478f5aSAxel Dörfler 440e478f5aSAxel Dörfler status_t 45c9dd7d0dSRene Gollent BSocket::Bind(const BNetworkAddress& local, bool reuseAddr) 460e478f5aSAxel Dörfler { 47c9dd7d0dSRene Gollent return BAbstractSocket::Bind(local, SOCK_STREAM, reuseAddr); 480e478f5aSAxel Dörfler } 490e478f5aSAxel Dörfler 500e478f5aSAxel Dörfler 510e478f5aSAxel Dörfler status_t 520e478f5aSAxel Dörfler BSocket::Connect(const BNetworkAddress& peer, bigtime_t timeout) 530e478f5aSAxel Dörfler { 540e478f5aSAxel Dörfler return BAbstractSocket::Connect(peer, SOCK_STREAM, timeout); 550e478f5aSAxel Dörfler } 560e478f5aSAxel Dörfler 570e478f5aSAxel Dörfler 58c9dd7d0dSRene Gollent status_t 59c9dd7d0dSRene Gollent BSocket::Accept(BAbstractSocket*& _socket) 60c9dd7d0dSRene Gollent { 61c9dd7d0dSRene Gollent int fd = -1; 62c9dd7d0dSRene Gollent BNetworkAddress peer; 63c9dd7d0dSRene Gollent status_t error = AcceptNext(fd, peer); 64c9dd7d0dSRene Gollent if (error != B_OK) 65c9dd7d0dSRene Gollent return error; 66c9dd7d0dSRene Gollent BSocket* socket = new(std::nothrow) BSocket(); 67c9dd7d0dSRene Gollent if (socket == NULL) { 68c9dd7d0dSRene Gollent close(fd); 69c9dd7d0dSRene Gollent return B_NO_MEMORY; 70c9dd7d0dSRene Gollent } 71c9dd7d0dSRene Gollent 72c9dd7d0dSRene Gollent socket->_SetTo(fd, fLocal, peer); 73c9dd7d0dSRene Gollent _socket = socket; 74c9dd7d0dSRene Gollent return B_OK; 75c9dd7d0dSRene Gollent } 76c9dd7d0dSRene Gollent 77c9dd7d0dSRene Gollent 780e478f5aSAxel Dörfler // #pragma mark - BDataIO implementation 790e478f5aSAxel Dörfler 800e478f5aSAxel Dörfler 810e478f5aSAxel Dörfler ssize_t 820e478f5aSAxel Dörfler BSocket::Read(void* buffer, size_t size) 830e478f5aSAxel Dörfler { 840e478f5aSAxel Dörfler ssize_t bytesReceived = recv(Socket(), buffer, size, 0); 850e478f5aSAxel Dörfler if (bytesReceived < 0) { 860e478f5aSAxel Dörfler TRACE("%p: BSocket::Read() error: %s\n", this, strerror(errno)); 870e478f5aSAxel Dörfler return errno; 880e478f5aSAxel Dörfler } 890e478f5aSAxel Dörfler 900e478f5aSAxel Dörfler return bytesReceived; 910e478f5aSAxel Dörfler } 920e478f5aSAxel Dörfler 930e478f5aSAxel Dörfler 940e478f5aSAxel Dörfler ssize_t 950e478f5aSAxel Dörfler BSocket::Write(const void* buffer, size_t size) 960e478f5aSAxel Dörfler { 970e478f5aSAxel Dörfler ssize_t bytesSent = send(Socket(), buffer, size, 0); 980e478f5aSAxel Dörfler if (bytesSent < 0) { 990e478f5aSAxel Dörfler TRACE("%p: BSocket::Write() error: %s\n", this, strerror(errno)); 1000e478f5aSAxel Dörfler return errno; 1010e478f5aSAxel Dörfler } 1020e478f5aSAxel Dörfler 1030e478f5aSAxel Dörfler return bytesSent; 1040e478f5aSAxel Dörfler } 1050e478f5aSAxel Dörfler 1060e478f5aSAxel Dörfler 1070e478f5aSAxel Dörfler // #pragma mark - private 1080e478f5aSAxel Dörfler 1090e478f5aSAxel Dörfler 1100e478f5aSAxel Dörfler void 1110e478f5aSAxel Dörfler BSocket::_SetTo(int fd, const BNetworkAddress& local, 1120e478f5aSAxel Dörfler const BNetworkAddress& peer) 1130e478f5aSAxel Dörfler { 1140e478f5aSAxel Dörfler Disconnect(); 1150e478f5aSAxel Dörfler 1160e478f5aSAxel Dörfler fInitStatus = B_OK; 1170e478f5aSAxel Dörfler fSocket = fd; 1180e478f5aSAxel Dörfler fLocal = local; 1190e478f5aSAxel Dörfler fPeer = peer; 120c9dd7d0dSRene Gollent fIsConnected = true; 1210e478f5aSAxel Dörfler 1220e478f5aSAxel Dörfler TRACE("%p: accepted from %s to %s\n", this, local.ToString().c_str(), 1230e478f5aSAxel Dörfler peer.ToString().c_str()); 1240e478f5aSAxel Dörfler } 125