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