From 83e8023c5e46635753a609329cf9805a3520001e Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Wed, 13 Feb 2008 22:53:01 +0000 Subject: network subsystem initial import --- src/net/tcpclient.cc | 119 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 src/net/tcpclient.cc (limited to 'src/net/tcpclient.cc') diff --git a/src/net/tcpclient.cc b/src/net/tcpclient.cc new file mode 100644 index 0000000..da5ff27 --- /dev/null +++ b/src/net/tcpclient.cc @@ -0,0 +1,119 @@ +/* + 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) + 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) { + // FIXME handle disconnect gracefully + con_print << "Client " << fd() << " disconnected." << std::endl; + disconnect(); + abort(); + return; + } else if (bytes_received < 0) { + con_warn << "Client " << fd() << " receive() error!" << std::endl; + // FIXME redirect error message + perror("recv"); + disconnect(); + abort(); + 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(); + return; + } + total_sent += bytes_sent; + + sendbuf.erase(sendbuf.size() - bytes_sent, bytes_sent); + } + + return; +} + +void TCPClient::disconnect() +{} + +} -- cgit v1.2.3