/* net/tcpclient.cc This file is part of the Osirion project and is distributed under the terms of the GNU General Public License version 2 */ #include #include #include #include #include "sys/sys.h" #include "net/net.h" #include "net/tcpclient.h" namespace net { TCPClient::TCPClient(int tcpclientfd) { tcpclient_fd = tcpclientfd; tcpclient_error = false; } TCPClient::~TCPClient() { if (tcpclient_fd != -1) { client_disconnect(); close(tcpclient_fd); } } bool TCPClient::error() const { return tcpclient_error; } bool TCPClient::valid() const { return (tcpclient_fd != -1); } bool TCPClient::invalid() const { return (tcpclient_fd == -1); } int TCPClient::fd() const { return (tcpclient_fd); } void TCPClient::abort() { tcpclient_error= true; } void TCPClient::receive(std::string &msg) { if (error() || invalid()) return; char recvbuf[FRAMESIZE]; // maximum block sizeq size_t msglen = sizeof(recvbuf); ssize_t bytes_received; memset(recvbuf, '\0', sizeof(recvbuf)); bytes_received = ::recv(tcpclient_fd, recvbuf, msglen, 0); if (bytes_received == 0) { //con_print << "Client " << fd() << " disconnected." << std::endl; client_disconnect(); abort(); return; } else if (bytes_received < 0) { //con_warn << "Client " << fd() << " receive() error!" << std::endl; // FIXME redirect error message perror("recv"); abort(); client_disconnect(); return; } msg = recvbuf; } void TCPClient::send(std::string const &msg) { if (error() || invalid()) return; if (msg.size() > FRAMESIZE) { con_warn << "Network message exceeds " << FRAMESIZE << " bytes!" << std::endl; return; } ssize_t bytes_sent = 0; size_t total_sent = 0; std::string sendbuf(msg); while (total_sent < msg.size()) { bytes_sent = ::send(tcpclient_fd, sendbuf.c_str(), sendbuf.size(), 0); if (bytes_sent < 0) { con_warn << "Client " << fd() << " send() error!" << std::endl; // FIXME redirect error message perror("send"); abort(); client_disconnect(); return; } total_sent += bytes_sent; sendbuf.erase(sendbuf.size() - bytes_sent, bytes_sent); } return; } void TCPClient::client_disconnect() { /* error() indicates if it was a clean disconnect or not */ } }