]> gitweb.hamatoma.de Git - crepublib/commitdiff
ReTCP.*
authorhama <hama@siduction.net>
Thu, 5 Mar 2015 17:03:18 +0000 (18:03 +0100)
committerhama <hama@siduction.net>
Thu, 5 Mar 2015 17:03:18 +0000 (18:03 +0100)
base/ReLogger.hpp
base/baselocations.hpp
base/rebase.hpp
cunit/cuReDirTools.cpp
cunit/testall.cpp
net/ReTCP.cpp [new file with mode: 0644]
net/ReTCP.hpp [new file with mode: 0644]
net/renet.hpp

index b1e99ecc8f8464dac211110bfe253e2019605cb6..f533c2f259bd2a979e9bda32f8cd21dfac7f5a87 100644 (file)
@@ -56,7 +56,7 @@ enum ReLogCategory {
        CAT_LIB = 0x00010000,
        CAT_OS = 0x00020000,
        CAT_FILE = 0x00040000,
-       CAT_PROG = 0x00080000,
+       CAT_PROCESS = 0x00080000,
        CAT_RESOURCE = 0x00100000,
        CAT_TEST = 0x00200000,
        CAT_SECURITY = 0x00400000,
index 39f9eab4fd02dd9b514b8e6dee9e813cc8f027f5..be561340c9f272bcd29c85e7ef50ffaac8466422 100644 (file)
@@ -18,6 +18,7 @@ enum RELOC_LIB {
        LC_SEQARRAY = 50200,
        LC_HASHLIST = 50300,
        LC_TRAVERSER = 50400,
+       LC_TCP = 50500,
 };
 enum RELOC_UDPCONNECTION {
        LC_UDPCONNECTION_CONSTRUCT = 50101,
index f37379d72b8771fc459c6bc2576f49e478421e74..beed8a9ca7aae5f65c532e1356afa46ee7c81d1f 100644 (file)
@@ -20,6 +20,7 @@
 #include <assert.h>
 #include <stdarg.h>
 #include <limits.h>
+#include <pthread.h>
 #define __LITTLE_ENDIAN__
 //#define __BIG_ENDIAN__
 
index 851eec40d8986944954e6c480affda494ae2700b..9eacdfd33dac491079fadc16fb957c7b5510efc4 100644 (file)
@@ -72,7 +72,7 @@ private:
                }\r
        }\r
        void testRandom(){\r
-               const char* argv[] = { "random", "-l10", "-s", "90", "100",\r
+               const char* argv[] = { "random", "-l20", "-s", "40", "50",\r
                    NULL };\r
                ReDirRandom(m_logger).run(-1, argv);\r
        }\r
index 38f4fb99e0986477bffd0f52f3ec8ad9e997bd8f..666afe400acf76e1be3aac762aea602ad509d9d0 100644 (file)
@@ -82,10 +82,10 @@ void testAll() {
        try {
                testOs();
                if (s_testAll) {
-                       testBase();
                        testString();
                        testMath();
                        testOs();
+                       testBase();
                }
        } catch (ReException e) {
                fprintf(stderr, "testBase.cpp: unexpected exception: %s\n",
diff --git a/net/ReTCP.cpp b/net/ReTCP.cpp
new file mode 100644 (file)
index 0000000..61d20cc
--- /dev/null
@@ -0,0 +1,345 @@
+/*
+ * ReTCP.cpp
+ *
+ *  Created on: 04.03.2015
+ *      Author: hm
+ */
+
+#include "base/rebase.hpp"
+#include "net/renet.hpp"
+
+enum LOCATION_DIRTOOL {
+       LC_LISTEN_FOR_ALL_1 = LC_TCP + 1, // 50501
+       LC_LISTEN_FOR_ALL_2,    // 50502
+       LC_LISTEN_FOR_ALL_3,    // 50503
+       LC_LISTEN_FOR_ALL_4,    // 50504
+       LC_LISTEN_FOR_ALL_5,    // 50505
+       LC_LISTEN_FOR_ALL_6,    // 50506
+       LC_WRITE_1,                     // 50507
+};
+
+/**
+ * Base class for TCP servers and clients.
+ */
+class ReTCPConnection {
+public:
+       ReTCPConnection(int id, ReLogger* logger);
+       virtual ~ReTCPConnection();
+public:
+       /**
+        * Returns the connection id.
+        * @return      the id
+        */
+       inline int id() const {
+               return m_id;
+       }
+       /**
+        * Returns the connection port.
+        * @return      the port
+        */
+       inline int port() const {
+               return m_port;
+       }
+       /**
+        * Returns the socket (ip:port).
+        * @return      a string describing the socket
+        */
+       const char* socketName() const{
+               return m_socketName.str();
+       }
+       void receive(ReByteBuffer& command, ReByteBuffer& message);
+       void send(const char* command, const char* message, int length = -1);
+       /** Sets the socket handle.
+        * @param handle        the socket handle to set
+        */
+       inline void setHandleSocket(int handle){
+               m_handleSocket = handle;
+       }
+       /** Sets the id
+        * @param id    the id to set
+        */
+       inline void setId(int id){
+               m_id = id;
+       }
+protected:
+       int m_port;
+       ReByteBuffer m_socketName;
+       ReByteBuffer m_received;
+       ReLogger* m_logger;
+       int m_handleSocket;
+       struct sockaddr_in m_address;
+       int m_id;
+       uint32_t m_noSent;
+       uint32_t m_noReceived;
+};
+
+class ReTCPServerConnection: public ReTCPConnection {
+public:
+       ReTCPServerConnection(int id, ReLogger* logger);
+       virtual ~ReTCPServerConnection();
+public:
+       void handleConnection();
+
+};
+/**
+ * Implements a multithreaded TCP server.
+ */
+class ReTCPServer: public ReTCPConnection {
+public:
+       ReTCPServer(ReLogger* logger, int maxConnections = 16);
+       virtual ~ReTCPServer();
+public:
+       bool listenForAll();
+private:
+       ReTCPServerConnection* createConnection(int id, int socket,
+           struct sockaddr& address);
+protected:
+       int m_maxConnections;
+       int m_countConnections;
+       ReTCPServerConnection** m_connections;
+};
+
+/**
+ * Implements a TCP client.
+ */
+class ReTCPClient: public ReTCPConnection {
+public:
+       ReTCPClient(ReLogger* logger);
+       virtual ~ReTCPClient();
+};
+
+/**
+ * Constructor.
+ *
+ * @param id           an identifier for logging
+ * @param logger       the logger for error handling
+ */
+ReTCPConnection::ReTCPConnection(int id, ReLogger* logger) :
+           m_port(0),
+           m_socketName(),
+           m_received(),
+           m_logger(logger),
+           m_handleSocket(-1),
+           // m_address
+           m_id(id),
+               m_noSent(0),
+               m_noReceived(0){
+       memset(&m_address, 0, sizeof m_address);
+}
+
+/**
+ * Destructor.
+ */
+ReTCPConnection::~ReTCPConnection() {
+}
+
+void ReTCPConnection::receive(ReByteBuffer& command, ReByteBuffer& message){
+
+}
+void ReTCPConnection::send(const char* command, const char* message,
+               int length){
+       if (length < 0)
+               length = strlen(message);
+       ReByteBuffer header;
+       ++m_noSent;
+       header.appendFix(command, -1, 8, 8, NULL).appendInt(length, "%08x");
+       header.append(reinterpret_cast<char*>(&m_noSent), sizeof m_noSent);
+       int error = 0;
+#if defined __linux__
+       if (write(m_handleSocket, header.str(), header.length()) != header.length())
+               error = getLastOSError();
+       if (write(m_handleSocket, message, length) != length)
+               error = getLastOSError();
+       error = error + 0;
+#elif defined __WIN32__
+#endif
+       if (error != 0){
+               error += 0;
+               m_logger->sayF(LOG_ERROR | CAT_NETWORK, LC_WRITE_1,
+                       i18n("Id=$1: cannot write ($1): $2"));
+               //.arg.(m_id)
+                       //      .arg(error).arg(m_socketName).end();
+       }
+}
+
+/**
+ * Constructor.
+ *
+ * @param id           an identifier for logging
+ * @param logger       the logger for error handling
+ */
+ReTCPServerConnection::ReTCPServerConnection(int id, ReLogger* logger) :
+           ReTCPConnection(id, logger) {
+}
+
+/**
+ * Destructor.
+ */
+ReTCPServerConnection::~ReTCPServerConnection(){
+}
+
+/**
+ * Constructor.
+ *
+ * @param logger                       the logger for error handling
+ * @param maxConnections       maximal count of threads handling a connection
+ */
+ReTCPServer::ReTCPServer(ReLogger* logger, int maxConnections) :
+           ReTCPConnection(0, logger),
+           m_maxConnections(maxConnections),
+           m_countConnections(0),
+           m_connections(new ReTCPServerConnection*[maxConnections]) {
+}
+
+/**
+ * Destructor.
+ */
+ReTCPServer::~ReTCPServer() {
+       for (int ii = 0; ii < m_countConnections; ii++) {
+               delete m_connections[ii];
+               m_connections[ii] = NULL;
+       }
+       delete[] m_connections;
+       m_connections = NULL;
+}
+
+ReTCPServerConnection* ReTCPServer::createConnection(int id, int socket,
+    struct sockaddr& address) {
+       ReTCPServerConnection* rc = NULL;
+
+       for (int ii = 0; ii < m_maxConnections; ii++) {
+               if (m_connections[ii] == NULL)
+                       m_connections[ii] = rc = new ReTCPServerConnection(id, m_logger);
+               else if (m_connections[ii]->id() < 0) {
+                       rc = m_connections[ii];
+                       rc->setId(id);
+               }
+       }
+       if (rc != NULL) {
+               rc->setHandleSocket(socket);
+               rc->setAddress(address);
+       }
+       return rc;
+}
+
+
+/**
+ * The start routine of pthread_start
+ *
+ * This will handle the connection for each client (in an own thread).
+ *
+ * @param pConnection  a void* pointer to the ReTCPServerConnection instance
+ * */
+void* connection_handler(void *pConnection) {
+       ReTCPServerConnection* connection =
+           reinterpret_cast<ReTCPServerConnection*>(pConnection);
+       connection->handleConnection();
+}
+
+
+/**
+ * Accepts connections and create a thread which will handle this connection.
+ */
+bool ReTCPServer::listenForAll() {
+       bool rc = false;
+       //Create socket
+       m_handleSocket = socket(AF_INET, SOCK_STREAM, 0);
+       if (m_handleSocket == -1) {
+               m_logger->sayF(LOG_ERROR | CAT_NETWORK, LC_LISTEN_FOR_ALL_1,
+                   i18n("cannot create a socket: $1")).arg(errno).end();
+       } else {
+               //Prepare the sockaddr_in structure
+               m_address.sin_family = AF_INET;
+               m_address.sin_addr.s_addr = INADDR_ANY;
+               m_address.sin_port = htons(m_port);
+
+               //Bind
+               if (bind(m_handleSocket, (struct sockaddr *) &m_address, sizeof(m_address))
+                   < 0) {
+                       m_logger->sayF(LOG_ERROR | CAT_NETWORK, LC_LISTEN_FOR_ALL_2,
+                           i18n("cannot bind: $1")).arg(
+                       errno).end();
+               } else {
+                       //Listen
+                       listen(m_handleSocket, 3);
+
+                       //Accept and incoming connection
+                       m_logger->sayF(LOG_INFO | CAT_NETWORK, LC_LISTEN_FOR_ALL_3,
+                           i18n("listening on $1...")).arg(m_port).end();
+                       int nextId = 1;
+                       //Accept and incoming connection
+                       int clientSocket;
+                       struct sockaddr addrClient;
+                       socklen_t lengthAddr = sizeof(struct sockaddr_in);
+                       while ((clientSocket = accept(m_handleSocket,
+                           (struct sockaddr *) &addrClient, &lengthAddr)) != 0) {
+                               m_logger->sayF(LOG_INFO | CAT_NETWORK, LC_LISTEN_FOR_ALL_4,
+                                   i18n("accepted: $1")).arg(m_port).end();
+                               if (m_countConnections >= m_maxConnections) {
+                                       // close the connection atonce:
+                                       m_logger->sayF(LOG_WARNING | CAT_NETWORK,
+                                           LC_LISTEN_FOR_ALL_5,
+                                           i18n("connection refused (too many connections): $1"))
+                                           .arg(m_port).end();
+                                       close(clientSocket);
+                               } else {
+                                       pthread_t sniffer_thread;
+                                       ReTCPConnection* connection = createConnection(nextId++,
+                                           clientSocket, addrClient);
+
+                                       if (pthread_create(&sniffer_thread, NULL,
+                                           connection_handler, (void*) connection) < 0) {
+                                               m_logger->sayF(LOG_ERROR | CAT_PROCESS,
+                                                   LC_LISTEN_FOR_ALL_6,
+                                                   i18n("cannot create a thread: $1")).arg(
+                                                   getLastOSError()).end();
+                                               close(clientSocket);
+                                       }
+
+                                       //Now join the thread , so that we dont terminate before the thread
+                                       //pthread_join( sniffer_thread , NULL);
+                                       puts("Handler assigned");
+                               }
+                       }
+
+                       if (clientSocket < 0) {
+                               perror("accept failed");
+                               return 1;
+                       }
+               }
+       }
+       return rc;
+}
+
+void ReTCPServerConnection::handleConnection() {
+       //Get the socket descriptor
+       int read_size;
+       char *message, client_message[2000];
+#if 0
+       receive(m_received, command);
+       if (! m_received.startsWith("login"))
+//Send some messages to the m_addrClient
+       message = "Greetings! I am your connection handler\n";
+       write(m_handleSocket, message, strlen(message));
+
+       message = "Now type something and i shall repeat what you type \n";
+       write(m_handleSocket, message, strlen(message));
+
+//Receive a message from m_addrClient
+       while ((read_size = recv(sock, client_message, 2000, 0)) > 0) {
+               //Send the message back to m_addrClient
+               write(m_handleSocket, client_message, strlen(client_message));
+       }
+
+       if (read_size == 0) {
+               puts("Client disconnected");
+               fflush(stdout);
+       } else if (read_size == -1) {
+               perror("recv failed");
+       }
+#endif
+//Free the socket pointer
+       close(m_handleSocket);
+       m_id = -1;
+}
+
diff --git a/net/ReTCP.hpp b/net/ReTCP.hpp
new file mode 100644 (file)
index 0000000..0f7d6a1
--- /dev/null
@@ -0,0 +1,11 @@
+/*
+ * ReTCP.hpp
+ *
+ *  Created on: 04.03.2015
+ *      Author: hm
+ */
+
+#ifndef NET_RETCP_HPP_
+#define NET_RETCP_HPP_
+
+#endif /* NET_RETCP_HPP_ */
index ba71b758aa8d3b634f46fd8937b5e71c37480868..33505cf3ada07202a0c332f5c5f10b40aa843aac 100644 (file)
@@ -9,5 +9,6 @@
 #define NET_RENET_HPP_
 
 #include "net/ReUdpConnection.hpp"
+#include "net/ReTCP.hpp"
 
 #endif /* NET_RENET_HPP_ */