diff --git a/program/Build/RaspberryCloud.sdf b/program/Build/RaspberryCloud.sdf
index 955739a198c833a77c7cebaa928dcbf56e7c235a..ae172f687a6ba1eeb16ae5ce9a64c5a413b51407 100644
Binary files a/program/Build/RaspberryCloud.sdf and b/program/Build/RaspberryCloud.sdf differ
diff --git a/program/Build/RaspberryCloud.v12.suo b/program/Build/RaspberryCloud.v12.suo
index d016c74cd39840bae5bc413c3ee67a2e37a4220f..c2be689bb2e0fc064d45f6722d5bbba67c3fae0e 100644
Binary files a/program/Build/RaspberryCloud.v12.suo and b/program/Build/RaspberryCloud.v12.suo differ
diff --git a/program/Build/RaspberryCloud/RaspberryCloud.vcxproj b/program/Build/RaspberryCloud/RaspberryCloud.vcxproj
index aca42221e628ce5508623c6789ff9017585b0c9d..87605e933ce98884180b9d5f497622c0d2617ffb 100644
--- a/program/Build/RaspberryCloud/RaspberryCloud.vcxproj
+++ b/program/Build/RaspberryCloud/RaspberryCloud.vcxproj
@@ -109,7 +109,9 @@
     <ClCompile Include="..\..\Source\fileModel\LockFile.cpp" />
     <ClCompile Include="..\..\Source\logger\Logger.cpp" />
     <ClCompile Include="..\..\Source\networking\ConcreteEncryption.cpp" />
+    <ClCompile Include="..\..\Source\networking\FileServerConnection.cpp" />
     <ClCompile Include="..\..\Source\networking\HomeNetworkCommunications.cpp" />
+    <ClCompile Include="..\..\Source\networking\IPServer.cpp" />
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\..\Source\app\Application.h" />
@@ -138,8 +140,11 @@
     <ClInclude Include="..\..\Source\fileModel\LockFile.h" />
     <ClInclude Include="..\..\Source\logger\Logger.h" />
     <ClInclude Include="..\..\Source\networking\ConcreteEncryption.h" />
+    <ClInclude Include="..\..\Source\networking\FileServerConnection.h" />
     <ClInclude Include="..\..\Source\networking\HomeNetworkCommunications.h" />
     <ClInclude Include="..\..\Source\networking\HomeNetworkEncryption.h" />
+    <ClInclude Include="..\..\Source\networking\IPServer.h" />
+    <ClInclude Include="..\..\Source\networking\NetworkHelperMethods.h" />
   </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
diff --git a/program/Build/RaspberryCloud/RaspberryCloud.vcxproj.filters b/program/Build/RaspberryCloud/RaspberryCloud.vcxproj.filters
index a0b9d38c5259d509a6dcc64e4d3a84ba21edac6d..d447ccf9cc8d692ca5dd302fbd70d779ebb8ffed 100644
--- a/program/Build/RaspberryCloud/RaspberryCloud.vcxproj.filters
+++ b/program/Build/RaspberryCloud/RaspberryCloud.vcxproj.filters
@@ -120,6 +120,12 @@
     <ClCompile Include="..\..\Source\cloud\FTPAdapter.cpp">
       <Filter>Source Files\cloud</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\Source\networking\FileServerConnection.cpp">
+      <Filter>Source Files\networking</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\networking\IPServer.cpp">
+      <Filter>Source Files\networking</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\..\Source\app\UI.h">
@@ -206,5 +212,14 @@
     <ClInclude Include="..\..\Source\cloud\FTPAdapter.h">
       <Filter>Header Files\cloud</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\Source\networking\FileServerConnection.h">
+      <Filter>Header Files\networking</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\networking\NetworkHelperMethods.h">
+      <Filter>Header Files\networking</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\networking\IPServer.h">
+      <Filter>Header Files\networking</Filter>
+    </ClInclude>
   </ItemGroup>
 </Project>
\ No newline at end of file
diff --git a/program/Build/RaspberryCloud/RaspberryCloud.vcxproj.user b/program/Build/RaspberryCloud/RaspberryCloud.vcxproj.user
index ef5ff2a1fae669e995b58fb11281de92ca5fab27..ff5921cf0d2fd9ab81317dc308955058e0042125 100644
--- a/program/Build/RaspberryCloud/RaspberryCloud.vcxproj.user
+++ b/program/Build/RaspberryCloud/RaspberryCloud.vcxproj.user
@@ -1,4 +1,8 @@
 <?xml version="1.0" encoding="utf-8"?>
 <Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <PropertyGroup />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <LocalDebuggerCommandArguments>
+    </LocalDebuggerCommandArguments>
+    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+  </PropertyGroup>
 </Project>
\ No newline at end of file
diff --git a/program/Source/app/Application.cpp b/program/Source/app/Application.cpp
index 0e6216a08ec18d086b1bfa9d69cee7ef1ed6a5aa..0bcd8f93cecfee788a9543b73c402d2fc701d226 100644
--- a/program/Source/app/Application.cpp
+++ b/program/Source/app/Application.cpp
@@ -7,6 +7,8 @@
 
 using namespace std;
 
+Application* Application::DeleteThisUglyWorkaround_App_Instance = nullptr;
+
 /**
  * Application implementation
  */
@@ -15,6 +17,8 @@ Application::Application(CloudManager cloudMan) : cm(cloudMan), cfs(*this){
 	LOG_ENTER_EXIT;
 }
 
+const string Application::SERVER = "server";
+
 /**
  * Entry method of the software
  * Initiates application 
@@ -31,16 +35,39 @@ int main(int argc, char **argv) {
 	cloudMan.addCloud(make_shared<FTPAdapter>());
 
 	Application application(cloudMan);
-	application.cal = CloudAccessLayer();
+	//application.cal = CloudAccessLayer();
 	application.cal.app = &application;
-	application.ui = app::UI();
+	//application.ui = app::UI();
 	application.ui.app = &application;
 
+	Application::DeleteThisUglyWorkaround_App_Instance = &application;
+
+	if (argc > 1 && (Application::SERVER.compare(argv[1]) == 0))
+	{
+		cout << "Starting in server mode!" << endl;
+		application.ui.setComputeOnPi(false);
+
+		application.ui.startServer();
+
+		cout << "To exit enter \"exit\"." << endl;
+		string command;
+		while (true)
+		{
+			cin >> command;
+
+			if (command == "exit")
+			{
+				return 0;
+			}
+		}
+	}
+
 	string command = "";
 	cout << "=================================================" << endl;
 	cout << "Welcome to the amazing RaspberryCloud application" << endl;
 	cout << "=================================================" << endl << endl;
 	cout << "Setting up system" << endl;
+	
 	while (true){
 		cout << "Please set home network behaviour (pi/client)" << endl;
 		string answer = "";
@@ -54,6 +81,7 @@ int main(int argc, char **argv) {
 			break;
 		}
 	}
+		
 
 	cout << "To list avaliable orders enter \"help\"." << endl;
 
@@ -69,6 +97,7 @@ int main(int argc, char **argv) {
 			cout << "To get the avaliable files   enter \"getFileList\"." << endl;
 			cout << "To delete a file             enter \"deleteFile\"." << endl;
 			cout << "To authorize a cloud adapter enter \"authCA\"." << endl;
+			cout << "To start or stop the server  enter \"serverCfg\"." << endl;
 		}
 		else if (command == "addFile"){
 			cout << "Adding file. Please enter local file id" << endl;
@@ -120,6 +149,17 @@ int main(int argc, char **argv) {
 			cin >> cloudAdapterId;
 			application.ui.authCloudAdapter(cloudAdapterId);
 		}
+		else if (command == "serverCfg")
+		{
+			string startOrStop;
+			cout << "Start or stop server?" << endl;
+			cin >> startOrStop;
+
+			if (startOrStop == "start")
+				application.ui.startServer(true);
+			else
+				application.ui.startServer(false);
+		}
 		else if (command == "exit"){
 			cout << "Bye! Thanks for choosing us." << endl;
 			return 0;
diff --git a/program/Source/app/Application.h b/program/Source/app/Application.h
index 77ce9f30aa4b221678039663481a84926101c451..890cdc142882a91d8018e4adee83e7db06f07fc2 100644
--- a/program/Source/app/Application.h
+++ b/program/Source/app/Application.h
@@ -14,6 +14,8 @@
  */
 class Application {
 public:
+	static const std::string SERVER;
+
 	CloudManager cm;
 	CloudAccessLayer cal;
 	CloudFileSystem cfs;
@@ -24,6 +26,9 @@ public:
 	 * Default Application constructor
 	 */
 	Application(CloudManager cm);
+
+
+	static Application* DeleteThisUglyWorkaround_App_Instance;
 };
 
 #endif //_APPLICATION_H
\ No newline at end of file
diff --git a/program/Source/app/UI.cpp b/program/Source/app/UI.cpp
index 524d6769dfd70e2fbd349a30c6e18b2f1dfe163b..f3535bd4a21049289df210c95a5407ce3604f242 100644
--- a/program/Source/app/UI.cpp
+++ b/program/Source/app/UI.cpp
@@ -66,4 +66,9 @@ list<FileDescriptor*>* UI::getFileTree() {
 	LOG_ENTER_EXIT;
 
 	return app->cfs.getFileTree();
+}
+
+void UI::startServer(bool start)
+{
+	app->hnc.startServer(start);
 }
\ No newline at end of file
diff --git a/program/Source/app/UI.h b/program/Source/app/UI.h
index 92bfa8af85d4e3e2f6c90e53778a2c7047213648..3ff5edf39b4be62b06c5e987561d7301fd378ecc 100644
--- a/program/Source/app/UI.h
+++ b/program/Source/app/UI.h
@@ -74,7 +74,17 @@ public:
 	*/
 	list<FileDescriptor*>* getFileTree();
 
+	/**
+	* Call auth function of a cloud adapter. 
+	* Used for example to aquire OAuth token.
+	*/
 	void authCloudAdapter(string cloudAdapterId);
+
+	/**
+	* Starts or stops the server functionality.
+	* @param start Start server if true, else stop.
+	*/
+	void startServer(bool start = true);
 };
 }
 #endif //_UI_H
\ No newline at end of file
diff --git a/program/Source/cloud/CloudAccessLayer.cpp b/program/Source/cloud/CloudAccessLayer.cpp
index 3ce456a73eeaa1a5a0d3bbdf1547ebf094c6c719..96a55f9863349bc5049884154a745fbbd3b472d3 100644
--- a/program/Source/cloud/CloudAccessLayer.cpp
+++ b/program/Source/cloud/CloudAccessLayer.cpp
@@ -3,8 +3,6 @@
 #include "app\Application.h"
 #include "CloudException.h"
 
-using namespace fileModel;
-
 /**
  * CloudAccessLayer implementation
  */
@@ -40,7 +38,7 @@ bool CloudAccessLayer::upload(const FileDescriptor& fileDescriptor) const
 	return succesful;
 }
 
-bool CloudAccessLayer::upload(LockFile lockFile) {
+bool CloudAccessLayer::upload(fileModel::LockFile lockFile) {
 	LOG_ENTER_EXIT;
 	bool success = true;
 	if (!(app->cm.getCloudAdapter(lockFile.getCloudId())->upload(lockFile))){
@@ -74,7 +72,7 @@ FileDescriptor* CloudAccessLayer::download(FileDescriptor fileDescriptor) {
 	return fd;
 }
 
-bool CloudAccessLayer::download(LockFile lockFile) {
+bool CloudAccessLayer::download(fileModel::LockFile lockFile) {
 	LOG_ENTER_EXIT;
 	if ((app->cm.getCloudAdapter(lockFile.getCloudId())->download(lockFile)) != NULL)
 		return true;
@@ -105,7 +103,7 @@ bool CloudAccessLayer::deleteFile(FileDescriptor fileDescriptor) {
 	return succesful;
 }
 
-bool CloudAccessLayer::deleteFile(LockFile lockFile) {
+bool CloudAccessLayer::deleteFile(fileModel::LockFile lockFile) {
 	LOG_ENTER_EXIT;
 	bool succesful = true;
 	if (!(app->cm.getCloudAdapter(lockFile.getCloudId())->deleteFile(lockFile))){
@@ -140,7 +138,7 @@ bool CloudAccessLayer::checkExists(FileDescriptor fileDescriptor) {
 	return exists;
 }
 
-bool CloudAccessLayer::checkExists(LockFile lockFile) {
+bool CloudAccessLayer::checkExists(fileModel::LockFile lockFile) {
 	LOG_ENTER_EXIT;
 
 	return (app->cm.getCloudAdapter(lockFile.getCloudId())->checkExists(lockFile));
diff --git a/program/Source/dataAccess/CloudFileSystem.cpp b/program/Source/dataAccess/CloudFileSystem.cpp
index 78474f37ac10861d6be2d576885bc4c88f5f17c2..ff700e2b48f6e5f5c584a427114fce2107af14ee 100644
--- a/program/Source/dataAccess/CloudFileSystem.cpp
+++ b/program/Source/dataAccess/CloudFileSystem.cpp
@@ -2,7 +2,11 @@
 #include "ComputeOnPi.h"
 #include "ComputeOnClient.h"
 
-using namespace fileModel;
+CloudFileSystem& CloudFileSystem::getInstance()
+{
+	return Application::DeleteThisUglyWorkaround_App_Instance->cfs;
+}
+
 
 /**
  * @file CloudFileSystem.cpp
@@ -10,14 +14,12 @@ using namespace fileModel;
  */
 
 CloudFileSystem::CloudFileSystem(Application &application) :
+		computeOnPi(false),
+		homeNetworkBehaviour(new ComputeOnClient(*this)),
 		application(application),
 		distributor(application.cm),
-		homeNetworkBehaviour(new ComputeOnClient(*this)),
-		cache(new ConcreteCache()),
-		computeOnPi(false)
+		cache(new ConcreteCache())
 {
-	//cfl = *(new CloudFileList());
-
 	cfl.setPersPath("store.dat");
 	cfl.load();
 
@@ -122,7 +124,7 @@ void CloudFileSystem::lock(FileDescriptor fileDescriptor) {
 		lockFileTmp << "Client ID comes here";
 		lockFileTmp.close();
 
-		LockFile lockFile(cloudId, lockFileName);
+		fileModel::LockFile lockFile(cloudId, lockFileName);
 		application.cal.upload(lockFile);
 	}
 }
@@ -132,7 +134,7 @@ void CloudFileSystem::unlock(FileDescriptor fileDescriptor) {
 
 	for each (string cloudId in fileDescriptor.getUniqueClouds())
 	{
-		LockFile lockFile(cloudId, fileDescriptor);
+		fileModel::LockFile lockFile(cloudId, fileDescriptor);
 		application.cal.deleteFile(lockFile);
 	}
 }
@@ -144,7 +146,7 @@ bool CloudFileSystem::isLocked(FileDescriptor fileDescriptor) {
 
 	for each (string cloudId in fileDescriptor.getUniqueClouds())
 	{
-		LockFile lockFile(cloudId, fileDescriptor);
+		fileModel::LockFile lockFile(cloudId, fileDescriptor);
 
 		if (application.cal.checkExists(lockFile))
 		{
diff --git a/program/Source/dataAccess/CloudFileSystem.h b/program/Source/dataAccess/CloudFileSystem.h
index 6c5530743e4ed83af026f9e9dd7f34e3f493ac41..d8b567c71a1550687da1a75926cd1787955a4872 100644
--- a/program/Source/dataAccess/CloudFileSystem.h
+++ b/program/Source/dataAccess/CloudFileSystem.h
@@ -59,6 +59,12 @@ private:
 	CloudFileList cfl;
 public: 
 
+	static CloudFileSystem& getInstance();
+	/*{
+		static CloudFileSystem instance;
+		return instance;
+	}*/
+
 	/**
 	 * Setter to the setComputePi variable
 	 * Sets the right HomeNetworkBehaviour
diff --git a/program/Source/dataAccess/ComputeOnClient.cpp b/program/Source/dataAccess/ComputeOnClient.cpp
index 3ad024d12c8e8cc989cbdd4fa88d2f231764e7de..48af852906ea0d83bfa52b41787c29cff532aeee 100644
--- a/program/Source/dataAccess/ComputeOnClient.cpp
+++ b/program/Source/dataAccess/ComputeOnClient.cpp
@@ -40,7 +40,7 @@ bool ComputeOnClient::addFile(string localFileID, string destinationFileID) {
 string ComputeOnClient::getFile(FileDescriptor fileDescriptor) {
 	LOG_ENTER_EXIT;
 
-	//TODO: check is anything is returned... where does it even return anything?
+	//TODO: check if anything is returned... where does it even return anything?
 	cloudFileSystem.getCache()->getFile();
 
 	if (cloudFileSystem.findByID(&fileDescriptor) == nullptr){
diff --git a/program/Source/dataAccess/ComputeOnPi.cpp b/program/Source/dataAccess/ComputeOnPi.cpp
index 654d9d5178473cbbe21d761dfa3e8aa25831dc1f..46124e508d3652191949c7db58341d7455e3f0c0 100644
--- a/program/Source/dataAccess/ComputeOnPi.cpp
+++ b/program/Source/dataAccess/ComputeOnPi.cpp
@@ -10,5 +10,5 @@ bool ComputeOnPi::addFile(string localFileID, string destinationFileID) {
 
 string ComputeOnPi::getFile(FileDescriptor fileDescriptor) {
 	//TODO: change HomeNetworkCommunications' getFileRemote's attribute's type to fileDescriptor
-	return cloudFileSystem.getHomeNetworkCommunications()->getFileRemote(fileDescriptor.getFileID());
+	return cloudFileSystem.getHomeNetworkCommunications()->getFileRemote(fileDescriptor.getFileID()) ? "File downloaded successfully" : "Could't download file";
 }
\ No newline at end of file
diff --git a/program/Source/networking/FileServerConnection.cpp b/program/Source/networking/FileServerConnection.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..0296b141babec840886f4ab3d2d8c8d060ad61d3
--- /dev/null
+++ b/program/Source/networking/FileServerConnection.cpp
@@ -0,0 +1,97 @@
+#include "FileServerConnection.h"
+#include <fstream>
+#include "NetworkHelperMethods.h"
+#include <dataAccess/CloudFileSystem.h>
+
+using namespace std;
+
+const std::string FileServerConnection::dataFolder = "C:\\Users\\krisz\\raspberrycloud\\skeleton\\Program\\data\\";
+
+void FileServerConnection::run()
+{
+	char buffer[1024];
+
+	socket().receiveBytes(buffer, sizeof(buffer));
+
+	if (GET_CMD.compare(buffer) == 0)
+	{
+		// GET command received, send OK
+		sendString(socket(), OK_ANS);
+
+		// Get file name
+		socket().receiveBytes(buffer, sizeof(buffer));
+		ifstream file(dataFolder + buffer, ios::in | ios::binary);
+
+		// If file doesn't exist try to get it
+		if (!file)
+		{
+			file.close();
+			CloudFileSystem::getInstance().getFile(FileDescriptor(buffer));
+			file.open(dataFolder + buffer, ios::in | ios::binary);
+
+			if (!file)
+			{
+				sendString(socket(), ERR_ANS);
+				return;
+			}
+		}
+
+		// Get file size and send it
+		long size = getFileSize(file);
+		socket().sendBytes(&size, sizeof(long));
+
+		socket().receiveBytes(buffer, sizeof(buffer));
+		if (OK_ANS.compare(buffer) != 0)
+			return;
+
+		// Send file
+		while (file)
+		{
+			file.read(buffer, sizeof(buffer));
+			socket().sendBytes(buffer, file.gcount());
+		}
+
+	}
+	else if (PUT_CMD.compare(buffer) == 0)
+	{
+		// PUT command received, send OK
+		sendString(socket(), OK_ANS);
+
+		// Get file size
+		long size;
+		socket().receiveBytes(&size, sizeof(long));
+
+		// File size received, send OK
+		sendString(socket(), OK_ANS);
+
+		// Get file name, create file
+		socket().receiveBytes(buffer, sizeof(buffer));
+		ofstream file(dataFolder + buffer, ios::out | ios::binary);
+		string fileName(buffer);
+
+		// If file is created send OK, else send ERR
+		if (file)
+		{
+			sendString(socket(), OK_ANS);
+		}
+		else
+		{
+			sendString(socket(), ERR_ANS);
+			return;
+		}
+
+		// Start receiving file
+		while (size != 0)
+		{
+			auto receivedBytes = socket().receiveBytes(buffer, sizeof(buffer));
+			file.write(buffer, receivedBytes);
+			size -= receivedBytes;
+		}
+
+		CloudFileSystem::getInstance().addFile(fileName, fileName);
+	}
+	else
+	{
+		sendString(socket(), ERR_ANS);
+	}
+}
diff --git a/program/Source/networking/FileServerConnection.h b/program/Source/networking/FileServerConnection.h
new file mode 100644
index 0000000000000000000000000000000000000000..02d015a516e39352298114dde93a1e721d6eafe0
--- /dev/null
+++ b/program/Source/networking/FileServerConnection.h
@@ -0,0 +1,16 @@
+#ifndef _FILESERVERCONNECTION_H
+#define _FILESERVERCONNECTION_H
+
+#include <Poco/Net/TCPServerConnection.h>
+
+class FileServerConnection : public Poco::Net::TCPServerConnection
+{
+	static const std::string dataFolder;
+
+public:
+	explicit FileServerConnection(const Poco::Net::StreamSocket& socket) : TCPServerConnection(socket) {}
+
+	virtual void run();
+};
+
+#endif //_FILESERVERCONNECTION_H
diff --git a/program/Source/networking/HomeNetworkCommunications.cpp b/program/Source/networking/HomeNetworkCommunications.cpp
index 28698cf08b962242879359f8e1a9323bb787f52e..fda709258cb3bd1c464f55c12781a275656b0c1c 100644
--- a/program/Source/networking/HomeNetworkCommunications.cpp
+++ b/program/Source/networking/HomeNetworkCommunications.cpp
@@ -1,34 +1,195 @@
 #include "logger\Logger.h"
 #include "HomeNetworkCommunications.h"
+#include "FileServerConnection.h"
+#include "NetworkHelperMethods.h"
+#include "IPServer.h"
+#include "Poco/Thread.h"
+#include "Poco/Net/TCPServerConnectionFactory.h"
+#include "Poco/Net/TCPServer.h"
+#include <Poco/Net/DatagramSocket.h>
+
 using namespace std;
+using namespace Poco;
+using namespace Poco::Net;
+
 /**
  * HomeNetworkCommunications implementation
  */
 
-HomeNetworkCommunications::HomeNetworkCommunications(){
-	encryption = ConcreteEncryption();
-}
+const string HomeNetworkCommunications::dataFolder = "C:\\Users\\krisz\\raspberrycloud\\skeleton\\Program\\dataClient\\";
 
-bool HomeNetworkCommunications::addFileRemote(string fileID) {
+HomeNetworkCommunications::HomeNetworkCommunications() :
+	tcpServer(nullptr),
+	udpServerThread(nullptr),
+	udpServer(nullptr)
+{}
+
+bool HomeNetworkCommunications::addFileRemote(string fileID) 
+{
 	LOG_ENTER_EXIT;
+
 	refresh();
-	if (!piAvaliable) return false;
-	string encrypted = encryption.encrypt(fileID);
-	cout << "REMOTE UPLOAD INITIATED." << endl;
+	if (!piAvaliable) 
+		return false;
+	
+	char buffer[1024];
+
+	// Open file, check if exists
+	ifstream file(dataFolder + fileID, ios::in | ios::binary);
+	if (!file)
+		return false;
+
+	// Create socket, connect to server
+	StreamSocket socket;
+	socket.connect(SocketAddress(piAddress, TCP_PORT));
+
+	// Send PUT command
+	sendString(socket, PUT_CMD);
+
+	socket.receiveBytes(buffer, sizeof(buffer));
+	if (OK_ANS.compare(buffer) != 0)
+		return false;
+
+	// Get file size and send it
+	long size = getFileSize(file);
+	socket.sendBytes(&size, sizeof(long));
+
+	socket.receiveBytes(buffer, sizeof(buffer));
+	if (OK_ANS.compare(buffer) != 0)
+		return false;
+
+	// Send file name
+	sendString(socket, fileID);
+
+	socket.receiveBytes(buffer, sizeof(buffer));
+	if (OK_ANS.compare(buffer) != 0)
+		return false;
+
+	// Send file
+	while (file)
+	{
+		file.read(buffer, sizeof(buffer));
+		socket.sendBytes(buffer, file.gcount());
+	}
+	
 	return true;
 }
 
-string HomeNetworkCommunications::getFileRemote(string fileID) {
+bool HomeNetworkCommunications::getFileRemote(string fileID) 
+{
 	LOG_ENTER_EXIT;
+
 	refresh();
-	if (!piAvaliable) return false;
-	string decrypted = encryption.decrypt(fileID);
-	cout << "REMOTE DOWNLOAD INITIATED." << endl;
-	return decrypted;
+	if (!piAvaliable) 
+		return false;
+	
+	char buffer[1024];
+	long size;
+
+	// Create socket, connect to server
+	StreamSocket socket;
+	socket.connect(SocketAddress(piAddress, TCP_PORT));
+
+	// Send GET command
+	sendString(socket, GET_CMD);
+
+	// Get server answer, exit if not OK
+	socket.receiveBytes(buffer, sizeof(buffer));
+	if (OK_ANS.compare(buffer) != 0)
+		return false;
+
+	// Send file name
+	sendString(socket, fileID);
+
+	// Get server answer, if ERR then exit
+	socket.receiveBytes(buffer, sizeof(buffer));
+	if (ERR_ANS.compare(buffer) == 0)
+		return false;
+
+	// If server answer wasn't ERR, it's the file size
+	memcpy(&size, buffer, sizeof(long));
+
+	// Send OK to server, start receiving file
+	sendString(socket, OK_ANS);
+
+	ofstream file(dataFolder + fileID, ios::out | ios::binary);
+	while (size != 0)
+	{
+		auto receivedBytes = socket.receiveBytes(buffer, sizeof(buffer));
+		file.write(buffer, receivedBytes);
+		size -= receivedBytes;
+	}
+
+	return true;
 }
 
-void HomeNetworkCommunications::refresh() {
+void HomeNetworkCommunications::refresh() 
+{
 	LOG_ENTER_EXIT;
-	cout << "THE PI IS READY." << endl;
-	piAvaliable = true;
-}
\ No newline at end of file
+	
+	try
+	{
+		piAddress = getServerIP();
+		piAvaliable = true;
+	}
+	catch (TimeoutException& e)
+	{
+		piAddress = IPAddress();
+		piAvaliable = false;
+	}
+}
+
+void HomeNetworkCommunications::startServer(bool start)
+{
+	if (start)
+	{
+		// Start IP server
+		if (udpServer == nullptr && udpServerThread == nullptr)
+		{
+			udpServer = new IPServer();
+			udpServerThread = new Thread();
+
+			udpServerThread->start(*udpServer);
+		}
+		
+		
+		// Start file server
+		if (tcpServer == nullptr)
+		{
+			tcpServer = new TCPServer(new TCPServerConnectionFactoryImpl<FileServerConnection>(), TCP_PORT);
+			tcpServer->start();
+		}
+	}
+	else
+	{
+		// Stop file server
+		delete tcpServer;
+		tcpServer = nullptr;
+
+		// Stop IP server
+		udpServer->stop();
+		udpServerThread->join();
+		delete udpServer;
+		delete udpServerThread;
+		udpServer = nullptr;
+		udpServerThread = nullptr;
+	}
+}
+
+IPAddress HomeNetworkCommunications::getServerIP()
+{
+	SocketAddress bdcast(IPAddress::broadcast(), UDP_PORT);
+	DatagramSocket dgs;
+
+	dgs.setBroadcast(true);
+	dgs.setReceiveTimeout(1000000);
+
+	string msg = "Hello server!";
+	dgs.sendTo(msg.c_str(), msg.size() + 1, bdcast);
+
+	SocketAddress sender;
+	char buffer[1024];
+	dgs.receiveFrom(buffer, sizeof(buffer), sender);
+
+	return sender.host();
+}
diff --git a/program/Source/networking/HomeNetworkCommunications.h b/program/Source/networking/HomeNetworkCommunications.h
index fb9137f443824dca1f88150138b151cda67cbc5f..41fb94fd8241c8e3a1f24c247bd2c4c02443f52f 100644
--- a/program/Source/networking/HomeNetworkCommunications.h
+++ b/program/Source/networking/HomeNetworkCommunications.h
@@ -1,21 +1,37 @@
-/**
- * Project Untitled
- */
-
-
 #ifndef _HOMENETWORKCOMMUNICATIONS_H
 #define _HOMENETWORKCOMMUNICATIONS_H
 
 #include <string>
-#include "ConcreteEncryption.h"
-using namespace std;
+#include <Poco/Net/IPAddress.h>
+
+namespace Poco { 
+	class Thread;
+	
+	namespace Net
+	{
+		class TCPServer;
+	} 
+}
+
+class IPServer;
+
 /**
  * HomeNetworkCommunications class
  * 
  */
 class HomeNetworkCommunications {
-private:
-	ConcreteEncryption encryption;
+
+	static const std::string dataFolder;
+
+	bool piAvaliable;
+	Poco::Net::IPAddress piAddress;
+
+	Poco::Net::TCPServer* tcpServer;
+	Poco::Thread* udpServerThread;
+	IPServer* udpServer;
+
+	Poco::Net::IPAddress getServerIP();
+
 public: 
 	/**
 	 * HomeNetworkCommunications constructor
@@ -26,20 +42,24 @@ public:
 	 * Sends a file to the PI be added remotely
 	 * @param fileID ID of the file to be added
 	 */
-	bool addFileRemote(string fileID);
+	bool addFileRemote(std::string fileID);
 
 	/**
 	 * Sends a file to the PI be added remotely
 	 * @param fileID ID of the file to be added
 	 */
-	string getFileRemote(string fileID);
+	bool getFileRemote(std::string fileID);
 	
 	/**
 	 * Checks if the pi is avaliable
 	 */
 	void refresh();
-private: 
-	bool piAvaliable;
+
+	/**
+	* Starts or stops the server functionality.
+	* @param start Start server if true, else stop.
+	*/
+	void startServer(bool start = true);
 };
 
 #endif //_HOMENETWORKCOMMUNICATIONS_H
\ No newline at end of file
diff --git a/program/Source/networking/IPServer.cpp b/program/Source/networking/IPServer.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ff2acb671f0e190b9940a71e8be475b84c20ad56
--- /dev/null
+++ b/program/Source/networking/IPServer.cpp
@@ -0,0 +1,33 @@
+#include "IPServer.h"
+#include <Poco/Net/IPAddress.h>
+#include <Poco/Net/DatagramSocket.h>
+#include "NetworkHelperMethods.h"
+
+using namespace Poco;
+using namespace Poco::Net;
+
+void IPServer::run()
+{
+	std::string welcomeMsg = "Hi!";
+
+	SocketAddress address(IPAddress(), UDP_PORT);
+	DatagramSocket socket(address);
+
+	socket.setReceiveTimeout(1000000);
+
+	char buffer[1024];
+	while (!stopped)
+	{
+		SocketAddress sender;
+
+		try
+		{
+			socket.receiveFrom(buffer, sizeof(buffer), sender);
+			socket.sendTo(welcomeMsg.c_str(), welcomeMsg.size() + 1, sender);
+		}
+		catch (TimeoutException& e)
+		{
+			// Timeout is used to let a thread check whether it should exit
+		}
+	}
+}
diff --git a/program/Source/networking/IPServer.h b/program/Source/networking/IPServer.h
new file mode 100644
index 0000000000000000000000000000000000000000..f773f1677dcf933f3c4cec3ffd9dbf82163a7476
--- /dev/null
+++ b/program/Source/networking/IPServer.h
@@ -0,0 +1,18 @@
+#ifndef _IPSERVER_H
+#define _IPSERVER_H
+#include <Poco/Runnable.h>
+
+class IPServer : public Poco::Runnable
+{
+	volatile bool stopped = false;
+
+public:
+	virtual void run();
+
+	void stop()
+	{
+		stopped = true;
+	}
+};
+
+#endif
diff --git a/program/Source/networking/NetworkHelperMethods.cpp b/program/Source/networking/NetworkHelperMethods.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/program/Source/networking/NetworkHelperMethods.h b/program/Source/networking/NetworkHelperMethods.h
new file mode 100644
index 0000000000000000000000000000000000000000..73872a2098369ea4791c7316b15687009c7ad720
--- /dev/null
+++ b/program/Source/networking/NetworkHelperMethods.h
@@ -0,0 +1,33 @@
+#ifndef _NETWORKHELPERMETHODS_H
+#define _NETWORKHELPERMETHODS_H
+
+#include <string>
+#include <Poco/Net/StreamSocket.h>
+#include <fstream>
+
+const int UDP_PORT = 42420;
+const int TCP_PORT = 42421;
+const std::string GET_CMD("GET");
+const std::string PUT_CMD("PUT");
+const std::string OK_ANS("OK");
+const std::string ERR_ANS("ERR");
+
+inline long getFileSize(std::ifstream& file)
+{
+	auto currPos = file.tellg();
+
+	file.seekg(0, file.beg);
+	auto begin = file.tellg();
+	file.seekg(0, file.end);
+	auto end = file.tellg();
+	file.seekg(0, currPos);
+
+	return end - begin;
+}
+
+inline void sendString(Poco::Net::StreamSocket& socket, const std::string string)
+{
+	socket.sendBytes(string.c_str(), string.size() + 1);
+}
+
+#endif //_NETWORKHELPERMETHODS_H