Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/net/tcpclient.cc')
-rw-r--r--src/net/tcpclient.cc119
1 files changed, 119 insertions, 0 deletions
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 <sys/types.h>
+#include <sys/socket.h>
+#include <assert.h>
+
+#include <iostream>
+
+#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()
+{}
+
+}