diff --git a/common/cpp/include/system_wrappers/io.h b/common/cpp/include/system_wrappers/io.h
index ebb62dfa58b63d52335ea8518ef6656a8e6f2c8a..c10e3591d52eef0f26b9ef42c9d9255cbd9fb69f 100644
--- a/common/cpp/include/system_wrappers/io.h
+++ b/common/cpp/include/system_wrappers/io.h
@@ -218,6 +218,8 @@ class IO {
     virtual size_t          Read            (FileDescriptor fd, void* buf, size_t length, Error* err) const = 0;
     virtual size_t          Write           (FileDescriptor fd, const void* buf, size_t length, Error* err) const = 0;
 
+    virtual Error          WriteDataToFile  (const std::string& fname, const FileData& data, size_t length) const = 0;
+
     virtual void            CreateNewDirectory      (const std::string& directory_name, Error* err) const = 0;
     virtual FileData        GetDataFromFile         (const std::string& fname, uint64_t fsize, Error* err) const = 0;
     virtual void CollectFileInformationRecursively(const std::string& path, std::vector<FileInfo>* files,
diff --git a/common/cpp/include/system_wrappers/system_io.h b/common/cpp/include/system_wrappers/system_io.h
index 52b7332bb16c6c0c90707041a3f7a273498ec4da..2a1703d7f4823a4ac53911a32fb217088888c191 100644
--- a/common/cpp/include/system_wrappers/system_io.h
+++ b/common/cpp/include/system_wrappers/system_io.h
@@ -101,6 +101,7 @@ class SystemIO final : public IO {
     size_t          Write(FileDescriptor fd, const void* buf, size_t length, Error* err) const;
     void            CreateNewDirectory(const std::string& directory_name, Error* err) const;
     FileData        GetDataFromFile(const std::string& fname, uint64_t fsize, Error* err) const;
+    Error           WriteDataToFile  (const std::string& fname, const FileData& data, size_t length) const;
     void            CollectFileInformationRecursively(const std::string& path, std::vector<FileInfo>* files,
                                                       Error* err) const;
     std::string     ReadFileToString(const std::string& fname, Error* err) const;
diff --git a/common/cpp/include/unittests/MockIO.h b/common/cpp/include/unittests/MockIO.h
index 1ce54ffed75c4ccec1d666eb76642759c76a2ace..262245a8b77c1708c454b99f35be7ef0652e8f1b 100644
--- a/common/cpp/include/unittests/MockIO.h
+++ b/common/cpp/include/unittests/MockIO.h
@@ -170,8 +170,16 @@ class MockIO : public IO {
         err->reset(error);
         return FileData(data);
     }
+
     MOCK_CONST_METHOD3(GetDataFromFile_t, uint8_t* (const std::string& fname, uint64_t fsize, ErrorInterface** err));
 
+    Error WriteDataToFile(const std::string& fname, const FileData& data, size_t length) const override {
+        return Error{WriteDataToFile_t(fname, data.get(), length)};
+
+    }
+
+    MOCK_CONST_METHOD3(WriteDataToFile_t, ErrorInterface * (const std::string& fname, uint8_t* data, size_t fsize));
+
     void CollectFileInformationRecursively(const std::string& path, std::vector<FileInfo>* files,
                                            Error* err) const override {
         ErrorInterface* error = nullptr;
diff --git a/common/cpp/src/system_io/system_io.cpp b/common/cpp/src/system_io/system_io.cpp
index 5b023f3ec637cb3635028ed7cf8c17903504aea8..d91eda9a4c508c78cd88f5ce69d7482853291946 100644
--- a/common/cpp/src/system_io/system_io.cpp
+++ b/common/cpp/src/system_io/system_io.cpp
@@ -121,6 +121,23 @@ void hidra2::SystemIO::CreateNewDirectory(const std::string& directory_name, Err
     }
 }
 
+Error SystemIO::WriteDataToFile(const std::string& fname, const FileData& data, size_t length) const {
+    Error err;
+    auto fd = Open(fname, IO_OPEN_MODE_CREATE_AND_FAIL_IF_EXISTS | IO_OPEN_MODE_RW, &err);
+    if (err) {
+        return err;
+    }
+
+    Write(fd, data.get(), length, &err);
+    if (err) {
+        return err;
+    }
+
+    Close(fd, &err);
+    return err;
+}
+
+
 std::string SystemIO::ReadFileToString(const std::string& fname, Error* err) const {
     auto info = GetFileInfo(fname, err);
     if (*err != nullptr) {
diff --git a/receiver/src/receiver_error.h b/receiver/src/receiver_error.h
index b82705288067bfcc6ee8df54d7384dc6c6e66fd0..63da34f6fe47518ca7d55278a47e82b0f302d7ed 100644
--- a/receiver/src/receiver_error.h
+++ b/receiver/src/receiver_error.h
@@ -7,6 +7,7 @@ namespace hidra2 {
 
 enum class ReceiverErrorType {
     kInvalidOpCode,
+    kBadRequest
 };
 
 //TODO Make a marco to create error class and error template class
@@ -51,6 +52,10 @@ namespace ReceiverErrorTemplates {
 auto const kInvalidOpCode = ReceiverErrorTemplate {
                                 "Invalid Opcode", ReceiverErrorType::kInvalidOpCode
                             };
+auto const kBadRequest = ReceiverErrorTemplate {
+                             "Bad request", ReceiverErrorType::kBadRequest
+                         };
+
 };
 }
 
diff --git a/receiver/src/request.cpp b/receiver/src/request.cpp
index 48d85e9dec781eeab7e0316d3a36818cd6c9026c..ef2794098cae92b3fa9a7840a2e25ff132e5f2de 100644
--- a/receiver/src/request.cpp
+++ b/receiver/src/request.cpp
@@ -4,7 +4,7 @@
 namespace hidra2 {
 
 Request::Request(const GenericNetworkRequestHeader& header,
-                 SocketDescriptor socket_fd) : io__{new SystemIO}, request_header_{header}, socket_fd_{socket_fd} {
+                 SocketDescriptor socket_fd) : io__{new SystemIO}, request_header_(header), socket_fd_{socket_fd} {
 }
 
 Error Request::AllocateDataBuffer() {
@@ -55,6 +55,19 @@ void Request::AddHandler(const RequestHandler* handler) {
 }
 
 
+uint64_t Request::GetDataSize() const {
+    return request_header_.data_size;
+}
+
+const FileData& Request::GetData() const {
+    return data_buffer_;
+}
+
+std::string Request::GetFileName() const {
+    return std::to_string(request_header_.data_id) + ".bin";
+}
+
+
 std::unique_ptr<Request> RequestFactory::GenerateRequest(const GenericNetworkRequestHeader&
         request_header, SocketDescriptor socket_fd,
         Error* err) const noexcept {
diff --git a/receiver/src/request.h b/receiver/src/request.h
index 8efcaf784c5476ed2c48e1009b626f44cf9507a7..dd45a8c7446057dbfe60a7e95a0ae045425adeef 100644
--- a/receiver/src/request.h
+++ b/receiver/src/request.h
@@ -18,6 +18,10 @@ class Request {
     Request(const GenericNetworkRequestHeader& request_header, SocketDescriptor socket_fd);
     void AddHandler(const RequestHandler*);
     const RequestHandlerList& GetListHandlers() const;
+    virtual uint64_t GetDataSize() const;
+    virtual std::string GetFileName() const;
+
+    virtual const FileData& GetData() const;
     std::unique_ptr<IO> io__;
   private:
     Error AllocateDataBuffer();
diff --git a/receiver/src/request_handler_file_write.cpp b/receiver/src/request_handler_file_write.cpp
index 6b509495df142cafd696a8e99f441d5f48b5b366..2796f6321f0f4561f35fab2ccdad7382eed52d23 100644
--- a/receiver/src/request_handler_file_write.cpp
+++ b/receiver/src/request_handler_file_write.cpp
@@ -1,10 +1,20 @@
 #include "request_handler_file_write.h"
 #include "system_wrappers/system_io.h"
-
+#include "request.h"
 namespace hidra2 {
 
 Error RequestHandlerFileWrite::ProcessRequest(const Request& request) const {
-    return nullptr;
+    auto fsize = request.GetDataSize();
+    if (fsize <= 0 || fsize > kMaxFileSize) {
+        return ReceiverErrorTemplates::kBadRequest.Generate();
+    }
+
+    const FileData& data = request.GetData();
+
+    auto fname = request.GetFileName();
+
+    return io__->WriteDataToFile("files/" + fname, data, fsize);
+
 }
 
 RequestHandlerFileWrite::RequestHandlerFileWrite() : io__{new SystemIO} {
diff --git a/receiver/src/request_handler_file_write.h b/receiver/src/request_handler_file_write.h
index bbffa8d3fb1dfb0960a4b53f9cbdde6040021764..fb56d4e25c5a3e313de22cab655e2d9e72b9aed8 100644
--- a/receiver/src/request_handler_file_write.h
+++ b/receiver/src/request_handler_file_write.h
@@ -7,6 +7,8 @@
 
 namespace hidra2 {
 
+const uint64_t kMaxFileSize = uint64_t(1024) * 1024 * 1024 * 2; //2GB
+
 class RequestHandlerFileWrite final: public RequestHandler {
   public:
     RequestHandlerFileWrite();
diff --git a/receiver/unittests/test_request_handler_file_write.cpp b/receiver/unittests/test_request_handler_file_write.cpp
index 2996f715912743876df9a39d6a469056db2431f4..d330b855c31be28bbf9bbe787ce27241309e47e3 100644
--- a/receiver/unittests/test_request_handler_file_write.cpp
+++ b/receiver/unittests/test_request_handler_file_write.cpp
@@ -9,6 +9,7 @@
 
 using ::testing::Test;
 using ::testing::Return;
+using ::testing::ReturnRef;
 using ::testing::_;
 using ::testing::DoAll;
 using ::testing::SetArgReferee;
@@ -44,7 +45,11 @@ class FileWriteHandlerTests : public Test {
   public:
     RequestHandlerFileWrite handler;
     NiceMock<MockIO> mock_io;
+    std::unique_ptr<MockRequest> mock_request;
     void SetUp() override {
+        GenericNetworkRequestHeader request_header;
+        request_header.data_id = 2;
+        mock_request.reset(new MockRequest{request_header, 1});
         handler.io__ = std::unique_ptr<hidra2::IO> {&mock_io};
         /*      ON_CALL(mock_io, Receive_t(socket_fd_, _, data_size_, _)).WillByDefault(
                   DoAll(SetArgPointee<3>(nullptr),
@@ -57,4 +62,53 @@ class FileWriteHandlerTests : public Test {
 
 };
 
+TEST_F(FileWriteHandlerTests, ErrorWhenZeroFileSize) {
+    EXPECT_CALL(*mock_request, GetDataSize())
+    .WillOnce(Return(0))
+    ;
+
+    auto err = handler.ProcessRequest(*mock_request);
+
+    ASSERT_THAT(err, Eq(hidra2::ReceiverErrorTemplates::kBadRequest));
+}
+
+TEST_F(FileWriteHandlerTests, ErrorWhenTooBigFileSize) {
+    EXPECT_CALL(*mock_request, GetDataSize())
+    .WillOnce(Return(hidra2::kMaxFileSize + 1))
+    ;
+
+    auto err = handler.ProcessRequest(*mock_request);
+
+    ASSERT_THAT(err, Eq(hidra2::ReceiverErrorTemplates::kBadRequest));
+}
+
+TEST_F(FileWriteHandlerTests, CallsWriteFile) {
+    std::string expected_file_name = "2.bin";
+    uint64_t expected_file_size = 10;
+    EXPECT_CALL(*mock_request, GetDataSize())
+    .WillOnce(Return(expected_file_size))
+    ;
+
+    hidra2::FileData data;
+    EXPECT_CALL(*mock_request, GetData())
+    .WillOnce(ReturnRef(data))
+    ;
+
+    EXPECT_CALL(*mock_request, GetFileName())
+    .WillOnce(Return(expected_file_name))
+    ;
+
+
+    EXPECT_CALL(mock_io, WriteDataToFile_t("files/"+expected_file_name, _, expected_file_size))
+    .WillOnce(
+        //Return(hidra2::IOErrorTemplates::kUnknownIOError.Generate().release())
+        Return(nullptr)
+    );
+
+    auto err = handler.ProcessRequest(*mock_request);
+
+    ASSERT_THAT(err, Eq(nullptr));
+}
+
+
 }
\ No newline at end of file
diff --git a/tests/producer_receiver/transfer_single_file/check_linux.sh b/tests/producer_receiver/transfer_single_file/check_linux.sh
index ae45360ab56d92b1ae1e92d5a6726b78138d56b5..163d4ab08b8144ea133ca0f6f48899b304234e63 100644
--- a/tests/producer_receiver/transfer_single_file/check_linux.sh
+++ b/tests/producer_receiver/transfer_single_file/check_linux.sh
@@ -14,6 +14,8 @@ nohup $2 &>/dev/null &
 sleep 0.3
 receiverid=`echo $!`
 
+mkdir files
+
 $1 localhost:4200 100 1
 
-du -b files/0.bin | cut -f1 | grep 100
+ls -ln files/0.bin | awk '{ print $5 }'| grep 100
diff --git a/tests/producer_receiver/transfer_single_file/check_windows.bat b/tests/producer_receiver/transfer_single_file/check_windows.bat
index a6076b28b2a8f4e96c8c3a1ca59b435842500cda..9413a82a228200e5a50ed87135e10450ab471714 100644
--- a/tests/producer_receiver/transfer_single_file/check_windows.bat
+++ b/tests/producer_receiver/transfer_single_file/check_windows.bat
@@ -5,6 +5,8 @@ start /B "" "%full_recv_name%"
 
 ping 1.0.0.0 -n 1 -w 100 > nul
 
+mkdir files
+
 %1 localhost:4200 100 1
 
 ping 1.0.0.0 -n 1 -w 100 > nul