diff --git a/NetworkingLib/include/DatagramReceiver.h b/NetworkingLib/include/DatagramReceiver.h
index 43c79d9da187a2d8494f5ab0763ce828ef6fa1c2..634e1c6cf8d870897ddbad1f511b62266bc1259f 100644
--- a/NetworkingLib/include/DatagramReceiver.h
+++ b/NetworkingLib/include/DatagramReceiver.h
@@ -47,7 +47,7 @@ public:
         : net(net)
           , bindingPort(bindingPort)
           , socket(net.getIoService(), Udp::v4())
-          , buffer(maxMessageSize)
+          , buffer(maxMessageSize + internal::Frame::HEADER_SIZE)
     {}
 
     Message receive(std::string & host, std::uint16_t & port, const time::Duration & timeout)
diff --git a/NetworkingLib/include/DatagramSender.h b/NetworkingLib/include/DatagramSender.h
index 942e1f35e1203c969ec663969be884e4360fd4cd..8a6012eac3550a96ee8386ac7e9e6b56319c372b 100644
--- a/NetworkingLib/include/DatagramSender.h
+++ b/NetworkingLib/include/DatagramSender.h
@@ -28,9 +28,7 @@ private:
 public:
     using Ptr = std::shared_ptr<DatagramSender>;
 
-    using SendHandler = std::function<void( const
-    error::ErrorCode & error
-    )>;
+    using SendHandler = std::function<void(const error::ErrorCode & error)>;
 
     using Udp = boost::asio::ip::udp;
     using Socket = Udp::socket;
diff --git a/NetworkingLib/include/Error.h b/NetworkingLib/include/Error.h
index c3f5f4a354a58a494c416bc6c164ecebd60de0a3..062d175252219bf93cefb6b4f2f8382f1d4628b5 100644
--- a/NetworkingLib/include/Error.h
+++ b/NetworkingLib/include/Error.h
@@ -38,7 +38,7 @@ protected:
     ErrorCode code;
 };
 
-class FailedOperation : Error
+class FailedOperation : public Error
 {
 public:
     FailedOperation()
@@ -46,7 +46,7 @@ public:
     {}
 };
 
-class Aborted : Error
+class Aborted : public Error
 {
 public:
     Aborted()
@@ -54,7 +54,7 @@ public:
     {}
 };
 
-class Busy : Error
+class Busy : public Error
 {
 public:
     Busy()
diff --git a/NetworkingLib/include/Frame.h b/NetworkingLib/include/Frame.h
index 18bca9d2cca36f146d5ce8257a3833dd96072565..26c840b19cab98525e0c03bc4448d08da214aa9d 100644
--- a/NetworkingLib/include/Frame.h
+++ b/NetworkingLib/include/Frame.h
@@ -17,6 +17,8 @@ namespace internal
 class Frame
 {
 public:
+    static constexpr std::size_t HEADER_SIZE = 4;
+
     Frame(const std::uint8_t * data, std::uint32_t numDataBytes)
         : data(data), numDataBytes(numDataBytes)
     {
diff --git a/NetworkingLib/include/Message.h b/NetworkingLib/include/Message.h
index 2887fd628cfab2dfd07bebc2356b633c3df53f1a..90fa9826b58b9a35b8d7eae87d4590c33b0c28ba 100644
--- a/NetworkingLib/include/Message.h
+++ b/NetworkingLib/include/Message.h
@@ -72,7 +72,7 @@ void asyncSend(Networking & net,
                boost::asio::ip::tcp::socket & socket,
                const Message & message,
                const time::Duration & timeout,
-               SendHandler handler)
+               const SendHandler & handler)
 {
     auto data = std::make_shared<std::string>(Encoder<Message>{}(message));
     networking::stream::asyncWrite(
@@ -100,7 +100,7 @@ void asyncReceive(Networking & net,
                   boost::asio::ip::tcp::socket & socket,
                   boost::asio::streambuf & buffer,
                   const time::Duration & timeout,
-                  ReceiveHandler<Message> handler)
+                  const ReceiveHandler<Message> & handler)
 {
     networking::stream::asyncRead(
         net, socket, buffer, timeout,
@@ -129,7 +129,7 @@ void asyncSendDatagramTo(Networking & net,
                          const std::string & host,
                          std::uint16_t port,
                          const time::Duration & timeout,
-                         SendToHandler handler)
+                         const SendToHandler & handler)
 {
     auto data = std::make_shared<std::string>(Encoder<Message>{}(message));
     networking::socket::asyncSendTo(
@@ -155,7 +155,7 @@ void asyncReceiveDatagramFrom(Networking & net,
                               boost::asio::ip::udp::socket & socket,
                               std::vector<char> & buffer,
                               const time::Duration & timeout,
-                              ReceiveFromHandler<Message> handler)
+                              const ReceiveFromHandler<Message> & handler)
 {
     networking::socket::asyncReceiveFrom(
         net, socket, buffer, timeout,
diff --git a/NetworkingLib/include/ServiceClient.h b/NetworkingLib/include/ServiceClient.h
index 8bb8b9538e0931d637eb6da782b9b35c9793a94d..9d8fb641a8e3e119e5425b93ff667d51f0a531a2 100644
--- a/NetworkingLib/include/ServiceClient.h
+++ b/NetworkingLib/include/ServiceClient.h
@@ -41,14 +41,15 @@ public:
 
     using CallHandler = std::function<void(const error::ErrorCode & error, ResponseMessage & response)>;
 
-    static Ptr create(Networking & net)
+    static Ptr create(Networking & net, std::size_t maxMessageSize = 512)
     {
-        return std::make_shared<Client<Service>>(PrivateTag{}, net);
+        return std::make_shared<Client<Service>>(PrivateTag{}, net, maxMessageSize);
     }
 
-    Client(PrivateTag, Networking & net)
+    Client(PrivateTag, Networking & net, std::size_t maxMessageSize = 512)
         : net(net)
           , socket(net.getIoService())
+          , maxMessageSize(maxMessageSize)
     {}
 
     ResponseMessage call(const std::string & host,
@@ -71,7 +72,7 @@ public:
         message::send(net, socket, request, timeout);
         updateTimeout(timeout, startTime);
         // Receive the response.
-        boost::asio::streambuf buffer;
+        boost::asio::streambuf buffer{maxMessageSize + internal::Frame::HEADER_SIZE};
         return message::receive<ResponseMessage>(net, socket, buffer, timeout);
     }
 
@@ -120,8 +121,7 @@ public:
                         // Receive the response.
                         networking::message::asyncReceive<ResponseMessage>(
                             state->self->net, state->self->socket, state->buffer, state->timeout,
-                            [state](auto const & error,
-                                                       auto & response)
+                            [state](auto const & error, auto & response)
                             {
                                 state->handler(error, response);
                             });
@@ -142,6 +142,7 @@ public:
 private:
     networking::Networking & net;
     Socket socket;
+    const std::size_t maxMessageSize;
 
     static void updateTimeout(time::Duration & timeout, time::TimePoint & startTime)
     {
@@ -169,6 +170,7 @@ private:
               , handler(handler)
               , timeout(timeout)
               , startTime(startTime)
+              , buffer(self->maxMessageSize + internal::Frame::HEADER_SIZE)
               , closer(self->socket)
         {}
 
@@ -178,7 +180,7 @@ private:
         time::Duration timeout;
         time::TimePoint startTime;
         boost::asio::streambuf buffer;
-        closeable::Closer<Socket> closer;
+        closeable::Closer <Socket> closer;
     };
 };
 
diff --git a/NetworkingLib/include/ServiceServer.h b/NetworkingLib/include/ServiceServer.h
index 9ac34e469236a26d0fe2f181f02ac8f3f4fdcde1..c11d8cb7cb4e3ce1cb93185d885533093c50c52d 100644
--- a/NetworkingLib/include/ServiceServer.h
+++ b/NetworkingLib/include/ServiceServer.h
@@ -37,18 +37,20 @@ public:
     std::function<ResponseMessage(const Endpoint & clientEndpoint,
                                   RequestMessage & requestMessage)>;
 
-    static Ptr create(Networking & net, uint16_t bindingPort)
+    static Ptr create(Networking & net, uint16_t bindingPort, std::size_t maxMessageSize = 512)
     {
-        return std::make_shared<Server<Service>>(PrivateTag{}, net, bindingPort);
+        return std::make_shared<Server<Service>>(PrivateTag{}, net, bindingPort, maxMessageSize);
     }
 
     // Should not be used outside.
     Server(PrivateTag,
            Networking & net,
-           uint16_t bindingPort)
+           uint16_t bindingPort,
+           std::size_t maxMessageSize)
         : net(net)
           , bindingPort(bindingPort)
           , acceptor(net.getIoService())
+          , maxMessageSize(maxMessageSize)
     {}
 
     void advertiseService(const RequestReceivedHandler & requestReceivedHandler)
@@ -72,6 +74,7 @@ private:
     std::uint16_t bindingPort;
     Acceptor acceptor;
     std::atomic<bool> running{false};
+    const std::size_t maxMessageSize;
 
     void accept(RequestReceivedHandler handler)
     {
@@ -119,13 +122,13 @@ private:
             });
     }
 
-private:
     struct AsyncState
     {
         AsyncState(Ptr self, const RequestReceivedHandler & requestReceivedHandler)
             : self(self)
               , socket(self->net.getIoService())
               , requestReceivedHandler(requestReceivedHandler)
+              , buffer(self->maxMessageSize + internal::Frame::HEADER_SIZE)
         {}
 
         Ptr self;
diff --git a/NetworkingLib/include/Socket.h b/NetworkingLib/include/Socket.h
index c61e01821f180377cb76ada52700836e9580297e..eb7e172e24603a7368cb7d7f24f935f05466444b 100644
--- a/NetworkingLib/include/Socket.h
+++ b/NetworkingLib/include/Socket.h
@@ -128,17 +128,17 @@ void sendTo(Networking & net,
     udp::endpoint endpoint{address::from_string(host), port};
 
     using namespace networking::internal;
-    Frame buffer{(const std::uint8_t *) sendData.c_str(), sendData.size()};
+    Frame frame{(const std::uint8_t *) sendData.c_str(), sendData.size()};
 
     auto asyncOperation = [&socket](auto && ... args)
     { socket.async_send_to(std::forward<decltype(args)>(args)...); };
 
     std::tuple<boost::system::error_code, std::size_t> result;
     closeable::timedOperation(
-        result, net, asyncOperation, socket, timeout, buffer.getBuffers(), endpoint);
+        result, net, asyncOperation, socket, timeout, frame.getBuffers(), endpoint);
 
     auto numBytesTransferred = std::get<1>(result);
-    if (numBytesTransferred < buffer.getSize())
+    if (numBytesTransferred < frame.getSize())
         throw error::FailedOperation{};
 };
 
@@ -155,18 +155,18 @@ void asyncSendTo(Networking & net,
     udp::endpoint endpoint{address::from_string(host), port};
 
     using namespace networking::internal;
-    auto buffer = std::make_shared<Frame>((const std::uint8_t *) sendData.c_str(), sendData.size());
+    auto frame = std::make_shared<Frame>((const std::uint8_t *) sendData.c_str(), sendData.size());
 
     auto asyncOperation = [&socket](auto && ... args)
     { socket.async_send_to(std::forward<decltype(args)>(args)...); };
 
     closeable::timedAsyncOperation(
         net, asyncOperation, socket, timeout,
-        [handler, buffer](const auto & networkingError,
+        [handler, frame](const auto & networkingError,
                           const auto & boostError,
                           auto numBytesTransferred)
         {
-            if (numBytesTransferred < buffer->getSize())
+            if (numBytesTransferred < frame->getSize())
             {
                 handler(error::codes::FAILED_OPERATION);
                 return;
@@ -174,7 +174,7 @@ void asyncSendTo(Networking & net,
 
             handler(networkingError);
         },
-        buffer->getBuffers(), endpoint);
+        frame->getBuffers(), endpoint);
 };
 
 template<typename DatagramSocket>
diff --git a/NetworkingLib/include/Stream.h b/NetworkingLib/include/Stream.h
index bf8a61df8a286cbf62154498bd7a1e428c72efbc..2088208bf029e8ab1f335a6c169c0cc65892735d 100644
--- a/NetworkingLib/include/Stream.h
+++ b/NetworkingLib/include/Stream.h
@@ -24,10 +24,9 @@ namespace internal
 
 std::string stringFromStreambuf(boost::asio::streambuf & streambuf, std::size_t numBytes);
 
-void numDataBytesFromBuffer(boost::asio::streambuf & streambuf,
-                            std::size_t numBytesTransferred,
-                            std::uint32_t & numDataBytes,
-                            std::uint32_t & numRemainingBytes);
+std::uint32_t numDataBytesFromBuffer(boost::asio::streambuf & streambuf);
+
+std::size_t getNumRemainingBytes(std::size_t numBytesTransferred, std::uint32_t numDataBytes);
 
 }
 
@@ -42,16 +41,16 @@ void write(Networking & net,
            const time::Duration & timeout)
 {
     using namespace networking::internal;
-    Frame buffer{(const std::uint8_t *) writeData.c_str(), writeData.size()};
+    Frame frame{(const std::uint8_t *) writeData.c_str(), writeData.size()};
 
     auto asyncOperation = [](auto && ... args)
     { boost::asio::async_write(std::forward<decltype(args)>(args)...); };
 
     std::tuple<boost::system::error_code, std::size_t> result;
-    closeable::timedOperation(result, net, asyncOperation, stream, timeout, stream, buffer.getBuffers());
+    closeable::timedOperation(result, net, asyncOperation, stream, timeout, stream, frame.getBuffers());
 
     auto numBytesTransferred = std::get<1>(result);
-    if (numBytesTransferred < buffer.getSize())
+    if (numBytesTransferred < frame.getSize())
         throw error::FailedOperation{};
 };
 
@@ -63,16 +62,16 @@ void asyncWrite(Networking & net,
                 const WriteHandler & handler)
 {
     using namespace networking::internal;
-    auto buffer = std::make_shared<Frame>((const std::uint8_t *) writeData.c_str(), writeData.size());
+    auto frame = std::make_shared<Frame>((const std::uint8_t *) writeData.c_str(), writeData.size());
 
     auto asyncOperation = [](auto && ... args)
     { boost::asio::async_write(std::forward<decltype(args)>(args)...); };
 
     closeable::timedAsyncOperation(
         net, asyncOperation, stream, timeout,
-        [handler, buffer](const auto & networkingError, const auto & boostError, auto numBytesTransferred)
+        [handler, frame](const auto & networkingError, const auto & boostError, auto numBytesTransferred)
         {
-            if (numBytesTransferred < buffer->getSize())
+            if (numBytesTransferred < frame->getSize())
             {
                 handler(error::codes::FAILED_OPERATION);
                 return;
@@ -80,7 +79,7 @@ void asyncWrite(Networking & net,
 
             handler(networkingError);
         },
-        stream, buffer->getBuffers());
+        stream, frame->getBuffers());
 }
 
 template<typename SyncReadStream>
@@ -89,7 +88,8 @@ std::string read(Networking & net,
                  boost::asio::streambuf & buffer,
                  time::Duration timeout)
 {
-    using namespace internal;
+    using networking::internal::Frame;
+    using namespace networking::stream::internal;
 
     auto startTime = time::now();
 
@@ -98,21 +98,30 @@ std::string read(Networking & net,
 
     std::tuple<boost::system::error_code, std::size_t> result;
 
-    // We receive 4 bytes first, giving us the number of data bytes.
+    // Receive frame header.
     closeable::timedOperation(
-        result, net, asyncOperation, stream, timeout, stream, buffer, boost::asio::transfer_at_least(4));
+        result, net, asyncOperation, stream, timeout, stream, buffer, boost::asio::transfer_at_least(Frame::HEADER_SIZE));
 
     auto numBytesTransferred = std::get<1>(result);
-    std::uint32_t numDataBytes, numRemainingBytes;
-    numDataBytesFromBuffer(buffer, numBytesTransferred, numDataBytes, numRemainingBytes);
-    if (numRemainingBytes == 0)
+    if (numBytesTransferred < Frame::HEADER_SIZE)
+        throw error::FailedOperation{};
+
+    auto numDataBytes = numDataBytesFromBuffer(buffer);
+    if (numDataBytes == 0)
+        return std::string{};
+
+    if (getNumRemainingBytes(numBytesTransferred, numDataBytes) == 0)
         return stringFromStreambuf(buffer, numDataBytes);
 
     timeout -= time::now() - startTime;
 
-    // Receive the actual data.
+    // Receive actual data.
     closeable::timedOperation(
-        result, net, asyncOperation, stream, timeout, stream, buffer, boost::asio::transfer_at_least(numRemainingBytes));
+        result, net, asyncOperation, stream, timeout, stream, buffer, boost::asio::transfer_at_least(numDataBytes));
+
+    numBytesTransferred = std::get<1>(result);
+    if (numBytesTransferred < numDataBytes)
+        throw error::FailedOperation{};
 
     return stringFromStreambuf(buffer, numDataBytes);
 };
@@ -124,47 +133,70 @@ void asyncRead(Networking & net,
                const time::Duration & timeout,
                const ReadHandler & handler)
 {
-    using namespace internal;
+    using networking::internal::Frame;
+    using namespace networking::stream::internal;
 
     auto startTime = time::now();
 
     auto asyncOperation = [](auto && ... args)
     { boost::asio::async_read(std::forward<decltype(args)>(args)...); };
 
+    // Receive frame header.
     closeable::timedAsyncOperation(
         net, asyncOperation, stream, timeout,
         [&net, &stream, &buffer, timeout, handler, startTime, asyncOperation]
             (const auto & networkingError, const auto & boostError, auto numBytesTransferred)
         {
+            std::string data{};
+
             if (networkingError)
             {
-                std::string noData{};
-                handler(networkingError, noData);
+                handler(networkingError, data);
                 return;
             }
 
-            std::uint32_t numDataBytes, numRemainingBytes;
-            numDataBytesFromBuffer(buffer, numBytesTransferred, numDataBytes, numRemainingBytes);
-            if (numRemainingBytes == 0)
+            if (numBytesTransferred < Frame::HEADER_SIZE)
             {
-                auto receiveData = stringFromStreambuf(buffer, numDataBytes);
-                handler(networkingError, receiveData);
+                handler(error::codes::FAILED_OPERATION, data);
+                return;
+            }
+
+            auto numDataBytes = numDataBytesFromBuffer(buffer);
+            if (numDataBytes == 0)
+            {
+                handler(networkingError, data);
+                return;
+            }
+
+            if (getNumRemainingBytes(numBytesTransferred, numDataBytes) == 0)
+            {
+                data = stringFromStreambuf(buffer, numDataBytes);
+                handler(networkingError, data);
                 return;
             }
 
             auto timeSpend = time::now() - startTime;
             auto newTimeout = timeout - timeSpend;
 
+            // Receive actual data.
             closeable::timedAsyncOperation(
                 net, asyncOperation, stream, newTimeout,
                 [&buffer, handler, numDataBytes](const auto & networkingError, const auto & boostError, auto numBytesTransferred)
                 {
-                    auto receiveData = stringFromStreambuf(buffer, numDataBytes);
-                    handler(networkingError, receiveData);
+                    std::string data{};
+
+                    if (numBytesTransferred < numDataBytes)
+                    {
+                        handler(error::codes::FAILED_OPERATION, data);
+                        return;
+                    }
+
+                    data = stringFromStreambuf(buffer, numDataBytes);
+                    handler(networkingError, data);
                 },
-                stream, buffer, boost::asio::transfer_at_least(numRemainingBytes));
+                stream, buffer, boost::asio::transfer_at_least(numDataBytes));
         },
-        stream, buffer, boost::asio::transfer_at_least(4));
+        stream, buffer, boost::asio::transfer_at_least(Frame::HEADER_SIZE));
 };
 
 }
diff --git a/NetworkingLib/src/Stream.cpp b/NetworkingLib/src/Stream.cpp
index 01b769bfe7ec1fafdc520cfc86f1c5e0ef569782..f4be80af697a91ace2a95f9df3f1375e4f04a12c 100644
--- a/NetworkingLib/src/Stream.cpp
+++ b/NetworkingLib/src/Stream.cpp
@@ -20,17 +20,19 @@ std::string stringFromStreambuf(boost::asio::streambuf & streambuf, std::size_t
     return data;
 }
 
-void numDataBytesFromBuffer(boost::asio::streambuf & streambuf,
-                            std::size_t numBytesTransferred,
-                            std::uint32_t & numDataBytes,
-                            std::uint32_t & numRemainingBytes)
+std::uint32_t numDataBytesFromBuffer(boost::asio::streambuf & streambuf)
 {
     auto numDataBytesStr = stringFromStreambuf(streambuf, 4);
-    numDataBytes = utils::bytesToInt<4, std::uint32_t>((const std::uint8_t *) numDataBytesStr.c_str());
+    return utils::bytesToInt<4, std::uint32_t>((const std::uint8_t *) numDataBytesStr.c_str());
+}
 
-    numRemainingBytes = 0;
-    if (numDataBytes > numBytesTransferred - 4)
-        numRemainingBytes = numDataBytes - numBytesTransferred - 4;
+std::size_t getNumRemainingBytes(std::size_t numBytesTransferred, std::uint32_t numDataBytes)
+{
+    using networking::internal::Frame;
+    std::size_t numRemainingBytes = 0;
+    if (numDataBytes > numBytesTransferred - Frame::HEADER_SIZE)
+        numRemainingBytes = numDataBytes - numBytesTransferred - Frame::HEADER_SIZE;
+    return numRemainingBytes;
 }
 
 }
diff --git a/NetworkingLib/test/Main.cpp b/NetworkingLib/test/Main.cpp
index 66fb4c1185dc1614424fbb119ebcd471541d4841..9b58d1a3bac8c0bac488170a0d672b848c7ee8dd 100644
--- a/NetworkingLib/test/Main.cpp
+++ b/NetworkingLib/test/Main.cpp
@@ -8,8 +8,10 @@
 
 int main(int argc, char ** argv)
 {
-    std::cout << "\ntestService\n\n";
-    networking::test::testServices();
+    std::cout << "\ntestSyncService\n\n";
+    networking::test::testSyncServices();
+    std::cout << "\ntestAsyncService\n\n";
+    networking::test::testAsyncServices();
     std::cout <<"\ntestTcpClientTimeout\n\n";
     networking::test::testTcpClientTimeout();
     std::cout <<"\ntestMultipleConnections\n\n";
@@ -30,5 +32,11 @@ int main(int argc, char ** argv)
     networking::test::testStringMessageOverDatagram();
     std::cout << "\ntestStringMessageOverService\n\n";
     networking::test::testStringMessageOverService();
+    std::cout << "\ntestServiceServerMaxMessageSize\n\n";
+    networking::test::testServiceServerMaxMessageSize();
+    std::cout << "\ntestServiceClientMaxMessageSize\n\n";
+    networking::test::testServiceClientMaxMessageSize();
+    std::cout << "\ntestDatagramReceiverMaxMessageSize\n\n";
+    networking::test::testDatagramReceiverMaxMessageSize();
     return 0;
 }
\ No newline at end of file
diff --git a/NetworkingLib/test/Test.cpp b/NetworkingLib/test/Test.cpp
index ee5f58ea6609c04d8d52a602b5c7755b2a473934..0cb6f2a00d755bdaf75c65be167f0e3006afed2d 100644
--- a/NetworkingLib/test/Test.cpp
+++ b/NetworkingLib/test/Test.cpp
@@ -21,7 +21,7 @@ namespace networking
 namespace test
 {
 
-void testServices()
+void testSyncServices()
 {
     using namespace protocol;
     Networking net1;
@@ -43,14 +43,74 @@ void testServices()
 
     sleep(1);
 
+    int correct = 0;
+
     auto client = service::Client<PlatoonService>::create(net2);
     for (int i = 0; i < 5; i++)
     {
-        auto response = client->call("127.0.0.1", 10001, PlatoonMessage::followerRequest(2), 5s);
+        auto response = client->call("127.0.0.1", 10001, PlatoonMessage::followerRequest(2), 1s);
         std::cout << "Response from " << (int) response.getVehicleId() << " with type: "
                   << (int) response.getMessageType()
                   << " and platoonId: " << (int) response.getPlatoonId() << "\n";
+        if (response.getVehicleId() == 1 && response.getPlatoonId() == 42)
+            correct++;
     }
+
+    if (correct == 5)
+        std::cout << "SUCCESS!\n";
+}
+
+void testAsyncServices()
+{
+    using namespace protocol;
+    Networking net;
+
+    auto server = service::Server<PlatoonService>::create(net, 10001);
+
+    server->advertiseService(
+        [](const auto & clientEndpoint,
+           auto & requestMessage) -> PlatoonMessage
+        {
+            std::cout << "Request from "
+                      << (int) requestMessage.getVehicleId()
+                      << " with type: "
+                      << (int) requestMessage.getMessageType()
+                      << "\n";
+            return PlatoonMessage::acceptResponse(1, 42);
+        });
+
+    sleep(1);
+
+    std::atomic<std::size_t> pending{5};
+    std::atomic<std::size_t> correct{0};
+
+    auto client = service::Client<PlatoonService>::create(net);
+    for (int i = 0; i < 5; i++)
+    {
+        client->asyncCall(
+            "127.0.0.1", 10001, PlatoonMessage::followerRequest(2), 1s,
+            [&pending, &correct](const auto & error, auto & response)
+            {
+                if (error)
+                    std::cout << "FAILED!\n";
+                else
+                {
+                    std::cout << "Response from " << (int) response.getVehicleId() << " with type: "
+                              << (int) response.getMessageType()
+                              << " and platoonId: " << (int) response.getPlatoonId() << "\n";
+                    if (response.getVehicleId() == 1 && response.getPlatoonId() == 42)
+                        correct++;
+                }
+
+                pending--;
+            });
+
+        while (client->isCalling());
+    }
+
+    while (pending > 0);
+    if (correct == 5)
+        std::cout << "SUCCESS!\n";
 }
 
 void testTcpClientTimeout()
@@ -118,11 +178,15 @@ void testMultipleConnections()
 
     auto client = service::Client<PlatoonService>::create(net3);
 
-    auto response = client->call("127.0.0.1", 10001, PlatoonMessage::followerRequest(1), 5s);
-    std::cout << "Response from " << response.getVehicleId() << std::endl;
+    auto response1 = client->call("127.0.0.1", 10001, PlatoonMessage::followerRequest(1), 5s);
+    std::cout << "Response from " << response1.getVehicleId() << std::endl;
+
+    auto response2 = client->call("127.0.0.1", 10002, PlatoonMessage::followerRequest(2), 5s);
+    std::cout << "Response from " << response2.getVehicleId() << std::endl;
 
-    response = client->call("127.0.0.1", 10002, PlatoonMessage::followerRequest(2), 5s);
-    std::cout << "Response from " << response.getVehicleId() << std::endl;
+    if (response1.getVehicleId() == 1 && response1.getPlatoonId() == 42 &&
+        response1.getVehicleId() == 2 && response1.getPlatoonId() == 43)
+        std::cout << "SUCCESS!\n";
 }
 
 void testStoppingServiceServer()
@@ -403,6 +467,138 @@ void testStringMessageOverService()
     receiverThread.join();
 }
 
+void testServiceServerMaxMessageSize()
+{
+    Networking net;
+
+    std::atomic<bool> running{true};
+    std::atomic<bool> syncCallError{false};
+
+    auto server = service::Server<StringService>::create(net, 10000, 100);
+    server->advertiseService(
+        [](auto && ...)
+        {
+            std::cout << "FAILED! (This should not have been called!\n";
+            return std::string{};
+        });
+
+    sleep(1);
+    auto client = service::Client<StringService>::create(net, 200);
+    try
+    {
+        client->call("127.0.0.1", 10000, std::string(200, 'a'), 1s);
+    }
+    catch (const error::Error &)
+    {
+        syncCallError = true;
+    }
+
+    client->asyncCall(
+        "127.0.0.1", 10000, std::string(200, 'a'), 1s,
+        [&syncCallError, &running](const auto & error, auto & message)
+        {
+            if (error == error::codes::FAILED_OPERATION && syncCallError)
+                std::cout << "SUCCESS!\n";
+
+            running = false;
+        });
+
+    while (running);
+}
+
+void testServiceClientMaxMessageSize()
+{
+    Networking net;
+
+    std::atomic<bool> running{true};
+    std::atomic<std::size_t> serverReceivedCount{0};
+    std::atomic<bool> syncCallError{false};
+
+    auto server = service::Server<StringService>::create(net, 10000, 200);
+    server->advertiseService(
+        [&serverReceivedCount](auto && ...)
+        {
+            serverReceivedCount++;
+            return std::string(200, 'a');
+        });
+
+    sleep(1);
+    auto client = service::Client<StringService>::create(net, 100);
+    try
+    {
+        client->call("127.0.0.1", 10000, std::string{}, 1s);
+    }
+    catch (const error::Error &)
+    {
+        syncCallError = true;
+    }
+
+    client->asyncCall(
+        "127.0.0.1", 10000, std::string(100, 'a'), 1s,
+        [&syncCallError, &running, &serverReceivedCount](const auto & error, auto & message)
+        {
+            if (error == error::codes::FAILED_OPERATION && syncCallError && serverReceivedCount == 2)
+                std::cout << "SUCCESS!\n";
+
+            running = false;
+        });
+
+    while (running);
+}
+
+void testDatagramReceiverMaxMessageSize()
+{
+    Networking net;
+
+    std::atomic<bool> asyncReceiveFailed{false};
+    std::atomic<bool> running{true};
+
+    auto receiver = message::DatagramReceiver<std::string>::create(net, 10000, 100);
+    auto sender = message::DatagramSender<std::string>::create(net);
+
+    receiver->asyncReceive(
+        1s,
+        [&asyncReceiveFailed, &running](const auto & error, auto && ... args)
+        {
+            if (error)
+                asyncReceiveFailed = true;
+            else
+                std::cout << "FAILED! (This should not be called!\n";
+
+            running = false;
+        });
+
+    sender->send(std::string(200, 'a'), "127.0.0.1", 10000, 1s);
+
+    while (running);
+
+    running = true;
+
+    std::thread receiveThread{
+        [&running, &asyncReceiveFailed, receiver]()
+        {
+            try
+            {
+                std::string host{};
+                std::uint16_t port;
+                receiver->receive(host, port, 3s);
+            }
+            catch (const error::Error &)
+            {
+                if (&asyncReceiveFailed)
+                    std::cout << "SUCCESS!\n";
+            }
+
+            running = false;
+        }};
+
+    sleep(1);
+    sender->send(std::string(200, 'a'), "127.0.0.1", 10000, 1s);
+
+    while (running);
+    receiveThread.join();
+}
+
 }
 }
 
diff --git a/NetworkingLib/test/Test.h b/NetworkingLib/test/Test.h
index d7b7e9ba2d50602717450f8c93ee9d7517ddd7b9..e519d005bf5d961860349784745a3fc21f48c6a5 100644
--- a/NetworkingLib/test/Test.h
+++ b/NetworkingLib/test/Test.h
@@ -19,7 +19,9 @@ public:
     using ResponseMessage = std::string;
 };
 
-void testServices();
+void testSyncServices();
+
+void testAsyncServices();
 
 void testTcpClientTimeout();
 
@@ -41,6 +43,12 @@ void testStringMessageOverDatagram();
 
 void testStringMessageOverService();
 
+void testServiceServerMaxMessageSize();
+
+void testServiceClientMaxMessageSize();
+
+void testDatagramReceiverMaxMessageSize();
+
 }
 }