]> gitweb.hamatoma.de Git - crepublib/commitdiff
dirtool TCP works with upload/download test
authorhama <hama@siduction.net>
Sun, 22 Mar 2015 16:56:10 +0000 (17:56 +0100)
committerhama <hama@siduction.net>
Sun, 22 Mar 2015 18:15:58 +0000 (19:15 +0100)
base/ReThread.cpp
base/ReThread.hpp
net/ReTCP.cpp
net/ReTCP.hpp
os/ReDirTools.cpp

index b7f638a02b459e94b99d7f67e0717484e1832411..512a850d179039b57760ac23e876dd1ace5c40a2 100644 (file)
@@ -33,7 +33,7 @@ ReThread::ReThread(bool autoDelete) :
            m_threadInfo(),\r
 #elif defined __WIN32__\r
            m_threadInfo(NULL),\r
-               m_osThreadId(0),\r
+           m_osThreadId(0),\r
 #endif\r
            m_shouldStop(false),\r
            m_isStopped(false),\r
@@ -86,12 +86,13 @@ bool ReThread::prepareToRun(int id, ReLogger* masterLogger,
     ReThreadPool* pool) {\r
        bool rc = false;\r
        if (m_pool != NULL) {\r
-               ReLogger* current = masterLogger == NULL ? globalLogger() : masterLogger;\r
+               ReLogger* current =\r
+                   masterLogger == NULL ? globalLogger() : masterLogger;\r
                current->sayF(LOG_ERROR | CAT_LIB, LC_PREPARE_TO_RUN_1,\r
                    i18n("prepareToRun($1) is called multiple times")).arg(id).end();\r
        } else {\r
                m_threadId = id;\r
-               if (m_appender != NULL){\r
+               if (m_appender != NULL) {\r
                        m_appender->setMasterLogger(masterLogger);\r
                } else {\r
                        m_appender = new ReSlaveAppender(masterLogger,\r
@@ -191,6 +192,32 @@ bool ReThreadPool::insertThread(ReThread* thread) {
 \r
        return found;\r
 }\r
+/**\r
+ * Returns the number of active threads.\r
+ *\r
+ * Inactive threads will be removed.\r
+ *\r
+ * @return     the number of running threads\r
+ */\r
+int ReThreadPool::countThreads() {\r
+       int count = 0;\r
+       m_mutexThreads.lock();\r
+       for (int ii = 0; ii < m_maxThreads; ii++) {\r
+               ReThread* current = m_threads[ii];\r
+               if (current != NULL) {\r
+                       if (!current->m_isStopped)\r
+                               count++;\r
+                       else {\r
+                               if (current->m_autoDelete)\r
+                                       delete current;\r
+                               m_threads[ii] = NULL;\r
+                       }\r
+               }\r
+       }\r
+       m_mutexThreads.unlock();\r
+       return count;\r
+}\r
+\r
 /**\r
  * Stopps all running threads.\r
  */\r
index 0d970e7c4083dc9d4f930049a3bc770a2107b906..29eaea6ec11500f59609508754250b21efb32658 100644 (file)
@@ -82,6 +82,7 @@ public:
        ReThreadPool(int maxThreads, ReLogger* logger);\r
        virtual ~ReThreadPool();\r
 public:\r
+       int countThreads();\r
        void killAllThreads();\r
        bool startSimpleThread(ReProcessor& processor);\r
        bool startThread(ReThread* thread);\r
index cd938e73078921e6940e88e0a829b465b6acec48..74adb0df661f7f0bd881c49b71021a4029fb91d5 100644 (file)
@@ -31,12 +31,33 @@ enum LOCATION_DIRTOOL {
        LC_SERVER_CONNECTION_RUN_1,     // 50520\r
        LC_SERVER_CONNECTION_RUN_2,     // 50521\r
        LC_SERVER_CONNECTION_RUN_3,     // 50522\r
+       LC_HANDLE_CONNECTION_4, // 50523\r
 };\r
 \r
 #if defined __WIN32__\r
 bool ReTCPConnection::isGlobalInitialized = false;\r
 #endif\r
 \r
+/**\r
+ * Constructor.\r
+ *\r
+ * @param message      the description of the exception\r
+ */\r
+ReTCPException::ReTCPException(const char* message) {\r
+\r
+}\r
+;\r
+\r
+/**\r
+ * Constructor.\r
+ *\r
+ * @param socket       the socket which is disconnected\r
+ */\r
+ReTCPDisconnectException::ReTCPDisconnectException(int socket) :\r
+           ReTCPException(i18n("disconnected")),\r
+           m_socket(socket) {\r
+}\r
+\r
 /**\r
  * Constructor.\r
  *\r
@@ -188,7 +209,8 @@ ReTCPConnection::ReTCPConnection(int id, ReLoggerOwner* loggerOwner) :
            m_handleSocket(-1),\r
            m_id(id),\r
            m_noSent(0),\r
-           m_noReceived(0) {\r
+           m_noReceived(0),\r
+           m_logSendReceive(true) {\r
 #if defined __WIN32__\r
        WSADATA wsaData;\r
        if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0) {\r
@@ -246,11 +268,16 @@ void ReTCPConnection::setConnectedAddress(int family, const char* ip,
  *\r
  * @param command      OUT: the received command\r
  * @param data         OUT: the received data\r
+ *\r
+ * @throws ReTCPBrokenPipeException\r
  */\r
 void ReTCPConnection::receive(ReByteBuffer& command, ReByteBuffer& data) {\r
        command.setLength(8);\r
        int received = recv(m_handleSocket, command.buffer(), 8, 0);\r
-       if (received != 8) {\r
+       if (received == 0) {\r
+               // connection closed from the peer\r
+               throw ReTCPDisconnectException(m_handleSocket);\r
+       } else if (received != 8) {\r
                m_loggerOwner->logger()->sayF(LOG_ERROR | CAT_NETWORK, LC_RECEIVE_1,\r
                    i18n("cannot receive ($1): $2 [$3]")).arg(errno).arg(received).arg(\r
                    m_peerName).end();\r
@@ -291,7 +318,7 @@ void ReTCPConnection::receive(ReByteBuffer& command, ReByteBuffer& data) {
                                m_loggerOwner->logger()->sayF(LOG_ERROR | CAT_NETWORK,\r
                                    LC_RECEIVE_4, i18n("too few bytes read: $1/$2 [$3]")).arg(\r
                                    readBytes).arg(received).arg(m_peerName).end();\r
-                       } else {\r
+                       } else if (m_logSendReceive) {\r
                                m_loggerOwner->logger()->sayF(LOG_DEBUG | CAT_NETWORK,\r
                                    LC_RECEIVE_5,\r
                                    i18n("received: $1 bytes in $2 round(s) [$3]: $4")).arg(\r
@@ -325,11 +352,14 @@ void ReTCPConnection::send(const char* command, const char* data, int length) {
        // add command length:\r
        int rest = length + 8;\r
        m_toSend.appendInt(rest | (flags << 24), "%08x");\r
+       // we send the flag/length too:\r
+       rest += 8;\r
        m_toSend.appendFix(command, -1, 8, 8, NULL);\r
        m_toSend.append(data, length);\r
        int sent = 0;\r
        const char* buf = m_toSend.str();\r
        int rounds = 0;\r
+\r
        while (rest > 0) {\r
                rounds++;\r
                if ((sent = ::send(m_handleSocket, buf, rest, 0)) > 0) {\r
@@ -341,7 +371,7 @@ void ReTCPConnection::send(const char* command, const char* data, int length) {
                        break;\r
                }\r
        }\r
-       if (rest == 0)\r
+       if (rest == 0 && m_logSendReceive)\r
                m_loggerOwner->logger()->sayF(LOG_DEBUG | CAT_NETWORK, LC_WRITE_2,\r
                    i18n("sent: $1 bytes in $2 round(s): $3 $4")).arg(length).arg(\r
                    rounds).arg(command).arg(\r
@@ -376,26 +406,34 @@ void ReTCPServerConnection::run() {
        ReByteBuffer command;\r
        ReNetCommandHandler::ProcessingState rc = ReNetCommandHandler::PS_UNDEF;\r
        m_loggerOwner->logger()->sayF(LOG_INFO | CAT_NETWORK,\r
-           LC_SERVER_CONNECTION_RUN_1, i18n("new connection to $1"))\r
-           .arg(m_name).end();\r
-       do {\r
-               receive(command, m_received);\r
-               rc = m_server->handler().handleNetCommand(command, m_received, this);\r
-               if (rc == ReNetCommandHandler::PS_UNKNOWN) {\r
-                       logger()->sayF(LOG_ERROR | CAT_NETWORK, LC_HANDLE_CONNECTION_1,\r
-                           i18n("unknown command: $1 length: $2")).arg(command).arg(\r
-                           m_received.length()).end();\r
-               }\r
-       } while (rc != ReNetCommandHandler::PS_STOP && !m_shouldStop);\r
-       m_pool->setShouldStop();\r
+           LC_SERVER_CONNECTION_RUN_1, i18n("new connection to $1")).arg(m_name)\r
+           .end();\r
+       try {\r
+               do {\r
+                       receive(command, m_received);\r
+                       rc = m_server->handler().handleNetCommand(command, m_received,\r
+                           this);\r
+                       if (rc == ReNetCommandHandler::PS_UNKNOWN) {\r
+                               logger()->sayF(LOG_ERROR | CAT_NETWORK, LC_HANDLE_CONNECTION_1,\r
+                                   i18n("unknown command: $1 length: $2")).arg(command).arg(\r
+                                   m_received.length()).end();\r
+                       }\r
+               } while (rc != ReNetCommandHandler::PS_STOP && !m_shouldStop);\r
+               m_pool->setShouldStop();\r
+       } catch (ReTCPDisconnectException& e) {\r
+               rc = ReNetCommandHandler::PS_CLOSED;\r
+       }\r
        close();\r
-       if (rc == ReNetCommandHandler::PS_STOP)\r
+       if (rc == ReNetCommandHandler::PS_CLOSED)\r
+               logger()->sayF(LOG_INFO | CAT_NETWORK, LC_HANDLE_CONNECTION_4,\r
+                   i18n("connection closed by the peer $1")).arg(m_peerName).end();\r
+       else if (rc == ReNetCommandHandler::PS_STOP)\r
                m_loggerOwner->logger()->sayF(LOG_INFO | CAT_NETWORK,\r
-                       LC_SERVER_CONNECTION_RUN_2, i18n("stop signal received from $1"))\r
-                       .arg(m_name).end();\r
+                   LC_SERVER_CONNECTION_RUN_2, i18n("stop signal received from $1"))\r
+                   .arg(m_name).end();\r
        else\r
                m_loggerOwner->logger()->say(LOG_INFO | CAT_NETWORK,\r
-                       LC_SERVER_CONNECTION_RUN_3, i18n("stop order received"));\r
+                   LC_SERVER_CONNECTION_RUN_3, i18n("stop order received"));\r
        m_id = -1;\r
 }\r
 \r
@@ -414,25 +452,18 @@ ReTCPServer::ReTCPServer(int port, class ReNetCommandHandler& commandHandler,
     ReLogger* logger, int maxConnections) :\r
            ReTCPConnection(0, this),\r
            m_maxConnections(maxConnections),\r
-           m_countConnections(0),\r
-           m_connections(new ReTCPServerConnection*[maxConnections]),\r
            m_handler(commandHandler),\r
-           m_logger(logger) {\r
+           m_logger(logger),\r
+           m_threadPool(maxConnections, logger) {\r
 #pragma warning( pop )\r
        m_port = port;\r
-       memset(m_connections, 0, maxConnections * sizeof *m_connections);\r
 }\r
 \r
 /**\r
  * Destructor.\r
  */\r
 ReTCPServer::~ReTCPServer() {\r
-       for (int ii = 0; ii < m_countConnections; ii++) {\r
-               delete m_connections[ii];\r
-               m_connections[ii] = NULL;\r
-       }\r
-       delete[] m_connections;\r
-       m_connections = NULL;\r
+       // m_poolConnections does the things!\r
 }\r
 /**\r
  * Creates a server connection.\r
@@ -444,15 +475,9 @@ ReTCPServer::~ReTCPServer() {
 ReTCPServerConnection* ReTCPServer::createConnection(int id, int handleSocket,\r
     const struct sockaddr& address) {\r
        ReTCPServerConnection* rc = NULL;\r
-       for (int ii = 0; rc == NULL && ii < m_maxConnections; ii++) {\r
-               if (m_connections[ii] == NULL)\r
-                       m_connections[ii] = rc = new ReTCPServerConnection(id, this);\r
-               else if (m_connections[ii]->id() < 0) {\r
-                       rc = m_connections[ii];\r
-                       rc->setId(id);\r
-               }\r
-       }\r
-       if (rc != NULL) {\r
+       if (m_threadPool.countThreads() < m_maxConnections) {\r
+               rc = new ReTCPServerConnection(id, this);\r
+               rc->setId(id);\r
                rc->setHandleSocket(handleSocket);\r
                char ip[INET6_ADDRSTRLEN];\r
                inet_ntop(address.sa_family,\r
@@ -476,7 +501,6 @@ bool ReTCPServer::listenForAll() {
        bool rc = false;\r
        struct addrinfo hints;\r
        struct addrinfo* addrInfo;\r
-       ReThreadPool pool(m_maxConnections + 1, m_logger);\r
 \r
 // first, load up address structs with getaddrinfo():\r
        memset(&hints, 0, sizeof hints);\r
@@ -524,8 +548,8 @@ bool ReTCPServer::listenForAll() {
                        socklen_t lengthAddr = sizeof(struct sockaddr_in);\r
                        while ((clientSocket = accept(m_handleSocket,\r
                            (struct sockaddr *) &addrClient, &lengthAddr)) != 0) {\r
-                               if (!pool.shouldStop()) {\r
-                                       if (m_countConnections >= m_maxConnections) {\r
+                               if (!m_threadPool.shouldStop()) {\r
+                                       if (m_threadPool.countThreads() >= m_maxConnections) {\r
                                                // close the connection at once:\r
                                                m_logger->sayF(LOG_WARNING | CAT_NETWORK,\r
                                                    LC_LISTEN_FOR_ALL_5,\r
@@ -536,7 +560,8 @@ bool ReTCPServer::listenForAll() {
                                        } else {\r
                                                ReTCPServerConnection* connection = createConnection(\r
                                                    nextId++, clientSocket, addrClient);\r
-                                               if (!pool.startThread(connection)) {\r
+                                               connection->setLogSendReceive(m_logSendReceive);\r
+                                               if (!m_threadPool.startThread(connection)) {\r
                                                        m_logger->sayF(LOG_ERROR | CAT_PROCESS,\r
                                                            LC_LISTEN_FOR_ALL_6,\r
                                                            i18n("cannot create a thread: $1")).arg(\r
@@ -549,7 +574,7 @@ bool ReTCPServer::listenForAll() {
                                        }\r
                                }\r
                        }\r
-                       if (pool.shouldStop()) {\r
+                       if (m_threadPool.shouldStop()) {\r
                                m_logger->say(LOG_INFO | CAT_PROCESS, LC_LISTEN_FOR_ALL_7,\r
                                    i18n("stop request received"));\r
                        }\r
index b9e620f0580c3748dc3560fa78969b645c93614e..05066bae1eec0721adb0fcb044d4f03cf877feb3 100644 (file)
 #elif defined __WIN32__
 #      define reCloseSocket(handle)    ::closesocket(handle)
 #endif
+
+/**
+ * Exceptions for TCP processing.
+ */
+class ReTCPException: public ReException {
+public:
+       ReTCPException(const char* message);
+};
+
+/**
+ * Exceptions when a connection is lost.
+ */
+class ReTCPDisconnectException: ReTCPException {
+public:
+       ReTCPDisconnectException(int socket);
+public:
+       int m_socket;
+};
+
 /**
  * Administrates the internal data of an ip address, usable for IP4 and IP6.
  */
@@ -94,6 +113,12 @@ public:
        inline void setId(int id) {
                m_id = id;
        }
+       /** Sets the flag for logging sending and/or receiving.
+        * @param value         <code>true</code>: the logging should be done
+        */
+       void setLogSendReceive(bool value) {
+               m_logSendReceive = value;
+       }
 protected:
        ReByteBuffer m_peerName;
        ReByteBuffer m_received;
@@ -102,12 +127,14 @@ protected:
        int m_id;
        uint32_t m_noSent;
        uint32_t m_noReceived;
+       bool m_logSendReceive;
 #if defined __WIN32__
 private:
        static bool isGlobalInitialized;
 #endif
 public:
        static void globalClose();
+
 };
 /**
  * Implements a TCP client.
@@ -122,7 +149,6 @@ public:
 private:
        ReLogger* m_logger;
 };
-
 class ReTCPServer;
 /**
  * Implements a single server connection to a client (in a single thread).
@@ -146,6 +172,7 @@ public:
            ReLogger* logger, int maxConnections = 16);
        virtual ~ReTCPServer();
 public:
+       ReTCPServerConnection* connectionByIndex(int index);
        /** Returns the command handler.
         * @return      the handler for the incoming messages
         */
@@ -160,10 +187,9 @@ private:
 
 protected:
        int m_maxConnections;
-       int m_countConnections;
-       ReTCPServerConnection** m_connections;
        ReNetCommandHandler& m_handler;
        ReLogger* m_logger;
+       ReThreadPool m_threadPool;
 };
 
 /**
@@ -177,6 +203,7 @@ public:
                PS_PROCESSED, // task has been successfully handled
                PS_FAILED, // task has been handled, error occurred
                PS_STOP,        // no further processing should be done
+               PS_CLOSED,      // connection has been closed by peer
        };
 public:
        ReNetCommandHandler();
index b054fae989a5a1ea2fb4390f9cf633490a20cc95..53ff136b0561bb441980f5bf845da5bf159fee74 100644 (file)
@@ -409,7 +409,7 @@ ReFileTime_t ReDirOptions::checkDate(const char* value) {
  * @return          the value (multiplied with the unit factor)\r
  * @throws          ReOptionExecption\r
  */\r
-time_t ReDirOptions::checkSize(const char* value) {\r
+int64_t ReDirOptions::checkSize(const char* value) {\r
        int64_t rc = 0;\r
        char unit = 'b';\r
        switch (sscanf(value, "%lld%c", (long long int*) &rc, &unit)) {\r
@@ -984,25 +984,25 @@ ReDirBatch::ReDirBatch(ReLogger* logger) :
            m_isExe(false) {\r
        // standard short options: D d O o P p T t v y Z z\r
        m_programArgs.addString("first",\r
-               i18n("defines the first line of the output"), '1', "first-line", true,\r
+           i18n("defines the first line of the output"), '1', "first-line", true,\r
 #if defined __linux__\r
-               "#! /bin/sh"\r
+           "#! /bin/sh"\r
 #elif defined __WIN32__\r
-               "rem this batch is created by dirtool"\r
+           "rem this batch is created by dirtool"\r
 #endif\r
-       );\r
+)      ;\r
        m_programArgs.addString("arguments", i18n("template for the output line.\n"\r
-               "Possible placeholders: (e.g. e:\\data\\sample.txt)\n"\r
-               "   !full!: e:\\data\\sample.txt\n"\r
-               "   !path!: e:\\data\\\n"\r
-               "   !basename!: sample.txt\n"\r
-               "   !name!: sample\n"\r
-               "   !ext!: .txt\n"\r
-               "example: --arguments='echo !basename! in !path! found'"), 'a',\r
-           "arguments", false, NULL);\r
+                       "Possible placeholders: (e.g. e:\\data\\sample.txt)\n"\r
+                       "   !full!: e:\\data\\sample.txt\n"\r
+                       "   !path!: e:\\data\\\n"\r
+                       "   !basename!: sample.txt\n"\r
+                       "   !name!: sample\n"\r
+                       "   !ext!: .txt\n"\r
+                       "example: --arguments='echo !basename! in !path! found'"), 'a',\r
+               "arguments", false, NULL);\r
        m_programArgs.addString("script",\r
-           i18n("name of the script (starts each output line)"), 'c', "script",\r
-           false, NULL);\r
+               i18n("name of the script (starts each output line)"), 'c', "script",\r
+               false, NULL);\r
 #if defined __WIN32__\r
        m_programArgs.addBool("isexe",\r
                i18n("supresses the starting 'call' of each output line"\r
@@ -1080,7 +1080,7 @@ void ReDirBatch::doIt() {
 #elif defined __WIN32__\r
        static const char* prefix = "rem ";\r
 #endif\r
-       printSummary (prefix);\r
+       printSummary(prefix);\r
 }\r
 \r
 /**\r
@@ -1834,7 +1834,7 @@ void ReDirTouch::processDir(ReDirStatus_t* entry) {
 \r
 static bool isAbsoluteTime(ReFileTime_t& time) {\r
 #if defined __linux__\r
-       static struct tm year1980 = {0, 0, 0, 1, 1 - 1, 1980 - 1900};\r
+       static struct tm year1980 = { 0, 0, 0, 1, 1 - 1, 1980 - 1900 };\r
        static time_t time1980 = mktime(&year1980);\r
        return time.tv_sec >= time1980;\r
 #elif defined __WIN32__\r
@@ -2078,47 +2078,47 @@ bool ReDirSync::copyFile(const char* source, ReFileProperties_t* properties,
        struct stat info;\r
        if (properties == NULL) {\r
                if (stat(source, &info) == 0)\r
-               properties = &info;\r
+                       properties = &info;\r
                else {\r
                        if (logger != NULL)\r
-                       logger->sayF(LOG_ERROR | CAT_FILE, LC_COPY_FILE_1,\r
-                               i18n("could not find: $1 (errno: $2)")).arg(source).arg(\r
+                               logger->sayF(LOG_ERROR | CAT_FILE, LC_COPY_FILE_1,\r
+                                   i18n("could not find: $1 (errno: $2)")).arg(source).arg(\r
                                errno).end();\r
                }\r
        }\r
        FILE* fpSource = fopen(source, "rb");\r
        if (fpSource == NULL) {\r
                if (logger != NULL)\r
-               logger->sayF(LOG_ERROR | CAT_FILE, LC_COPY_FILE_2,\r
-                       i18n("cannot open $1 (errno: $2)")).arg(source).arg(errno).end();\r
+                       logger->sayF(LOG_ERROR | CAT_FILE, LC_COPY_FILE_2,\r
+                           i18n("cannot open $1 (errno: $2)")).arg(source).arg(errno).end();\r
        } else {\r
                ReFileSize_t size =\r
-               properties == NULL ? 0x7fffffff : properties->st_size;\r
+                   properties == NULL ? 0x7fffffff : properties->st_size;\r
                FILE* fpTarget = fopen(target, "w");\r
                if (fpTarget == NULL) {\r
                        if (logger != NULL)\r
-                       logger->sayF(LOG_ERROR | CAT_FILE, LC_COPY_FILE_3,\r
-                               i18n("cannot open $1 (errno: $2)")).arg(target).arg(errno)\r
-                       .end();\r
+                               logger->sayF(LOG_ERROR | CAT_FILE, LC_COPY_FILE_3,\r
+                                   i18n("cannot open $1 (errno: $2)")).arg(target).arg(errno)\r
+                                   .end();\r
                } else {\r
                        while (size > 0) {\r
                                size_t blockSize = buffer.capacity();\r
                                if ((int) blockSize > size)\r
-                               blockSize = size;\r
+                                       blockSize = size;\r
                                if (fread(buffer.buffer(), blockSize, 1, fpSource) != 1) {\r
                                        if (logger != NULL)\r
-                                       logger->sayF(LOG_ERROR | CAT_FILE, LC_COPY_FILE_5,\r
-                                               i18n("cannot read $1 (errno: $2)")).arg(source).arg(\r
+                                               logger->sayF(LOG_ERROR | CAT_FILE, LC_COPY_FILE_5,\r
+                                                   i18n("cannot read $1 (errno: $2)")).arg(source).arg(\r
                                                errno).end();\r
                                        break;\r
                                }\r
                                size_t written;\r
                                if ((written = fwrite(buffer.buffer(), 1, blockSize, fpTarget))\r
-                                       != blockSize) {\r
+                                   != blockSize) {\r
                                        if (logger != NULL)\r
-                                       logger->sayF(LOG_ERROR | CAT_FILE, LC_COPY_FILE_6,\r
-                                               i18n("cannot write $1 [$2] (errno: $3)")).arg(\r
-                                               target).arg(written).arg(errno).end();\r
+                                               logger->sayF(LOG_ERROR | CAT_FILE, LC_COPY_FILE_6,\r
+                                                   i18n("cannot write $1 [$2] (errno: $3)")).arg(\r
+                                                   target).arg(written).arg(errno).end();\r
                                        break;\r
                                }\r
                                size -= blockSize;\r
@@ -2126,7 +2126,7 @@ bool ReDirSync::copyFile(const char* source, ReFileProperties_t* properties,
                        rc = size == 0ll;\r
                        fclose(fpTarget);\r
                        if (properties != NULL)\r
-                       setProperties(target, properties, logger);\r
+                               setProperties(target, properties, logger);\r
                }\r
                fclose(fpSource);\r
        }\r
@@ -2159,24 +2159,24 @@ bool ReDirSync::setProperties(const char* fullName,
        times[1].tv_usec = properties->st_mtim.tv_nsec / 1000;\r
        if (utimes(fullName, times) != 0) {\r
                if (logger != NULL)\r
-               logger->sayF(LOG_ERROR | CAT_FILE, LC_SET_PROPERTIES_1,\r
-                       i18n("cannot change file times: $1 (errno: $2)")).arg(fullName)\r
-               .arg(errno).end();\r
+                       logger->sayF(LOG_ERROR | CAT_FILE, LC_SET_PROPERTIES_1,\r
+                           i18n("cannot change file times: $1 (errno: $2)")).arg(fullName)\r
+                           .arg(errno).end();\r
                rc = false;\r
        }\r
        int rights = properties->st_mode & (S_IRWXO | S_IRWXG | S_IRWXU);\r
        if (chmod(fullName, rights) != 0) {\r
                if (logger != NULL)\r
-               logger->sayF(LOG_ERROR | CAT_FILE, LC_SET_PROPERTIES_2,\r
-                       i18n("cannot change file modes: $1 (errno: $2)")).arg(fullName)\r
-               .arg(errno).end();\r
+                       logger->sayF(LOG_ERROR | CAT_FILE, LC_SET_PROPERTIES_2,\r
+                           i18n("cannot change file modes: $1 (errno: $2)")).arg(fullName)\r
+                           .arg(errno).end();\r
                rc = false;\r
        }\r
        if (chown(fullName, properties->st_uid, properties->st_gid) != 0) {\r
                if (logger != NULL)\r
-               logger->sayF(LOG_ERROR | CAT_FILE, LC_SET_PROPERTIES_3,\r
-                       i18n("cannot change file owner: $1 (errno: $2)")).arg(fullName)\r
-               .arg(errno).end();\r
+                       logger->sayF(LOG_ERROR | CAT_FILE, LC_SET_PROPERTIES_3,\r
+                           i18n("cannot change file owner: $1 (errno: $2)")).arg(fullName)\r
+                           .arg(errno).end();\r
                rc = false;\r
        }\r
 #endif\r
@@ -2362,9 +2362,11 @@ void ReDirSync::doIt() {
 ReDirTCP::ReDirTCP(ReLogger* logger) :\r
            ReTool(s_tcpUsage, s_tcpExamples, 1, 0, 0, true, logger) {\r
        m_hasStandardArgs = false;\r
-       m_programArgs.addInt("size",\r
-           i18n("size of the message to send/receive (in KiByte)"), 'b',\r
-           "--buffer-size", 64);\r
+       m_programArgs.addString("size", i18n("size of the message to send/receive\n"\r
+               "<string> is a number followed by an unit\n"\r
+               "units: b(yte) k(Byte) K(iByte) m(Byte), M(iByte)\n"\r
+               "Note: maximum: 16M-32=16777184\n"\r
+               "examples: -b1m --buffer-size=512K"), 'b', "size", false, "64K");\r
        m_programArgs.addInt("port", i18n("port of the server/client"), 'p',\r
            "--port", 58111);\r
 }\r
@@ -2374,11 +2376,16 @@ ReDirTCP::ReDirTCP(ReLogger* logger) :
  */\r
 void ReDirTCP::doIt() {\r
        int port = m_programArgs.getInt("port");\r
-       int bufferSize = m_programArgs.getInt("size") * 1024;\r
-\r
+       ReByteBuffer buffer;\r
+       int64_t bufferSize = checkSize(m_programArgs.getString("size", buffer));\r
+       // the protocol does not allow more than 16 MiByte because of the flags:\r
+       if (bufferSize > 16LL * 1024 * 1024 - 64LL)\r
+               help(i18n("buffersize exceeds 16777184 = 16MiByte - 32: "),\r
+                   buffer.str());\r
        ReByteBuffer command = m_programArgs.arg(0);\r
        if (command.isPrefixOf("server", -1, true)) {\r
                ReTCPEchoServer server(port, m_logger);\r
+               server.setLogSendReceive(false);\r
                server.listenForAll();\r
        } else if (command.isPrefixOf("client", -1, true)) {\r
                const char* ip = m_programArgs.arg(1);\r
@@ -2399,9 +2406,9 @@ void ReDirTCP::doIt() {
                if (m_programArgs.argCount() > 4)\r
                        interval = atoi(m_programArgs.arg(4));\r
                if (tolower(direction.at(0)) == 'm')\r
-                       runMixedClient(ip, port, rounds, interval, bufferSize);\r
+                       runMixedClient(ip, port, rounds, interval, (int) bufferSize);\r
                else\r
-                       runOneThreadClient(ip, port, rounds, interval, bufferSize,\r
+                       runOneThreadClient(ip, port, rounds, interval, (int) bufferSize,\r
                            tolower(direction.at(0)) == 'u');\r
        } else\r
                help("unknown subcommand: $1", command.str());\r
@@ -2425,6 +2432,7 @@ void ReDirTCP::runOneThreadClient(const char* ip, int port, int rounds,
                int64_t size = 0;\r
                int duration = 0;\r
                ReByteBuffer answer, data;\r
+               client.setLogSendReceive(false);\r
                for (int ii = 0; ii < rounds; ii++) {\r
                        client.send(command, message.str(), message.length());\r
                        client.receive(answer, data);\r
@@ -2442,7 +2450,8 @@ void ReDirTCP::runOneThreadClient(const char* ip, int port, int rounds,
                if (duration == 0)\r
                        duration = 1;\r
                printf("%2d: %9.3f MiByte %8.3f kiByte %s/sec %s\n", rounds,\r
-                   size / 1024.0 / 1024, (double) size / duration / 1024, upload ? "up" : "down");\r
+                   size / 1024.0 / 1024, (double) size / duration / 1024,\r
+                   upload ? "up" : "down");\r
 \r
        }\r
 }\r
@@ -2461,13 +2470,13 @@ ReDirWhich::ReDirWhich(ReLogger* logger) :
            false,\r
            NULL);\r
        m_programArgs.addString("separator",\r
-               i18n("separator between the path elements"), 's', "separator", false,\r
+           i18n("separator between the path elements"), 's', "separator", false,\r
 #if defined __linux__\r
-               ":"\r
+           ":"\r
 #elif defined __WIN32__\r
-               ";"\r
+           ";"\r
 #endif\r
-       );\r
+)      ;\r
        m_programArgs.addString("variable", i18n("variable with the path list"),\r
            'v', "variable", false, "PATH");\r
        m_hasStandardArgs = false;\r