From 9b6c992bb7b0a6ca7d00bb9196cc5e6e5cda69e5 Mon Sep 17 00:00:00 2001 From: Daniel M <daniel.q.mueller@stud.h-da.de> Date: Tue, 11 May 2021 23:32:34 +0200 Subject: [PATCH] Add sendAll readAll functions --- inc/tcpstream.hpp | 32 ++++++++++++++++++++++++++++++++ src/tcpstream.cpp | 43 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+) diff --git a/inc/tcpstream.hpp b/inc/tcpstream.hpp index d2b7408..05f69c5 100644 --- a/inc/tcpstream.hpp +++ b/inc/tcpstream.hpp @@ -106,6 +106,19 @@ public: */ ssize_t send(const void *data, size_t len); + /** + * @brief Send exactly len bytes of data into the tcp connection. + * + * If sending fails, an exception is thrown. + * + * @param data Pointer to at least len bytes that will be sent over the + * tcp connection. + * @param len The number of bytes that will be sent over the tcp connection. + * + * @return The number of bytes that were actually sent over the connection. + */ + void sendAll(const void *data, size_t len); + /** * @brief Receive a maximum of len bytes of data from the tcp connection. It * is possible that less than len bytes are received. This call will block @@ -123,6 +136,25 @@ public: */ ssize_t read(void *data, size_t len); + /** + * @brief Read exactly len bytes from the tcp stream. If the connection is + * closed before len bytes are read, the number of bytes actually read is + * returned. This will block until exactly len bytes are read or the + * connection is closed. + * + * If receiving failed or the connection is closed before at least one + * byte was received, an exception is thrown. + * + * @param data Pointer to at least len bytes where the data received over + * the tcp connection will be stored. + * @param len The number of bytes that will be received over the tcp + * connection. + * + * @return The number of bytes that were actually received over the + * connection. This can be less than len if the connection is closed. + */ + ssize_t readAll(void *data, size_t len); + /** * @brief Get the socket address of the connection target. * diff --git a/src/tcpstream.cpp b/src/tcpstream.cpp index 09bd214..b470516 100644 --- a/src/tcpstream.cpp +++ b/src/tcpstream.cpp @@ -92,6 +92,27 @@ ssize_t TcpStream::send(const void *data, size_t len) return bytes_sent; } +void TcpStream::sendAll(const void *data, size_t len) +{ + if (sockfd == 0) + throw std::runtime_error("Can't write to closed socket"); + + size_t bytesSentTotal = 0; + + while (bytesSentTotal < len) + { + ssize_t bytesSent = ::write(sockfd, (uint8_t*)data + bytesSentTotal, len-bytesSentTotal); + + if (bytesSent < 0) + { + close(); + throw std::runtime_error("Error while writing to socket"); + } + + bytesSentTotal += bytesSent; + } +} + ssize_t TcpStream::read(void *data, size_t len) { if (sockfd == 0) @@ -106,6 +127,28 @@ ssize_t TcpStream::read(void *data, size_t len) return bytes_read; } +ssize_t TcpStream::readAll(void *data, size_t len) +{ + if (sockfd == 0) + throw std::runtime_error("Can't read from closed socket"); + + size_t bytesReadTotal = 0; + while (true) + { + ssize_t bytesRead = ::read(sockfd, (uint8_t*)data + bytesReadTotal, len-bytesReadTotal); + + if (bytesRead == 0) break; + if (bytesRead < 0) + { + close(); + throw std::runtime_error("Error while reading from socket"); + } + + bytesReadTotal += bytesRead; + } + return bytesReadTotal; +} + const SockAddr & TcpStream::getRemoteAddr() const { return remote; -- GitLab