Skip to content
This repository has been archived by the owner on Aug 15, 2022. It is now read-only.

Send File

Peter Halasz edited this page Feb 13, 2019 · 2 revisions

Forge Networking works with all kinds of data, but that doesn't exclude sending files across the network. At the end of the day, files are just an array of bytes (byte[]) and by now, you probably know you can send that stuff over the network with Forge Networking. So let's get started with a simple desktop->desktop file transfer shall we!

The Setup

To get started we are going to need to setup our environment so that we can quickly and easily test our code. So let's open up a project with Forge Networking imported into it to get started.

  1. Download the deal-with-it.jpg image (cat image below)
  2. Open project with Forge Networking imported
  3. Create a folder named FileTransfer
  4. Copy the deal-with-it.jpg image into the FileTransfer folder
  5. Create a new scene and save it into the FileTransfer folder named FileTransferTest
  6. Create a C# script in the FileTransfer folder named SendThatFile
  7. Open that script in your favorite editor
  8. Put the following code into the script

Deal With It!

Note that this code is not optimized but made simple for quick understanding

using BeardedManStudios;
using BeardedManStudios.Forge.Networking;
using BeardedManStudios.Forge.Networking.Frame;
using BeardedManStudios.Forge.Networking.Unity;
using System.IO;
using UnityEngine;

public class SendThatFile : MonoBehaviour
{
	public string filePath;
	private bool sentFile;

	private void Start()
	{
		NetworkManager.Instance.Networker.binaryMessageReceived += ReceiveFile;
	}

	private void ReceiveFile(NetworkingPlayer player, Binary frame, NetWorker sender)
	{
		// We are looking to read a very specific message
		if (frame.GroupId != MessageGroupIds.START_OF_GENERIC_IDS + 1)
			return;

		Debug.Log("Reading file!");

		// Read the string from the beginning of the payload
		string fileName = frame.StreamData.GetBasicType<string>();

		Debug.Log("File name is " + fileName);

		if (File.Exists(fileName))
		{
			Debug.LogError("The file " + fileName + " already exists!");
			return;
		}

		// Write the rest of the payload as the contents of the file and
		// use the file name that was extracted as the file's name
		File.WriteAllBytes(fileName, frame.StreamData.CompressBytes());
	}

	private void Update()
	{
		if (Input.GetKeyDown(KeyCode.Space) && !sentFile)
		{
			sentFile = true;

			// Throw an error if this is not the server
			var networker = NetworkManager.Instance.Networker;
			if (!networker.IsServer)
			{
				Debug.LogError("Only the server can send files in this example!");
				return;
			}

			// Throw an error if the file does not exist
			if (!File.Exists(filePath))
			{
				Debug.LogError("The file " + filePath + " could not be found");
				return;
			}

			// Prepare a byte array for sending
			BMSByte allData = new BMSByte();
			
			// Add the file name to the start of the payload
			ObjectMapper.Instance.MapBytes(allData, Path.GetFileName(filePath));

			// Add the data to the payload
			allData.Append(File.ReadAllBytes(filePath));

			// Send the file to all connected clients
			Binary frame = new Binary(
				networker.Time.Timestep,					// The current timestep for this frame
				false,                                      // We are server, no mask needed
				allData,									// The file that is being sent
				Receivers.Others,							// Send to all clients
				MessageGroupIds.START_OF_GENERIC_IDS + 1,   // Some random fake number
				networker is TCPServer);

			if (networker is UDPServer)
				((UDPServer)networker).Send(frame, true);
			else
				((TCPServer)networker).SendAll(frame);
		}
	}
}

Preparing to run

  1. Open the Unity build menu
  2. Add the MultiplayerMenu scene as the first scene
  3. Add the FileTransferTest as the second scene
  4. Open the Player Settings...
  5. Turn on run in background
  6. Open the FileTransferTest scene
  7. Select the camera or any object in the scene
  8. Add the SendThatFile script to the object
  9. Update the File Path field on the script to have the full path to the deal-with-it.jpg image inside of the FileTransfer folder
  10. Save the scene
  11. Build and Run
  12. Open 2 instances of the game
  13. Set one to be the server then connect with the other
  14. Press the spacebar on the server
  15. Go into the build folder for the player and then go up a directory, you will notice a deal-with-it.jpg has been created

Home

Getting Started
Network Contract Wizard (NCW)
Network Object
Remote Procedure Calls (RPCs)
Unity Integration
Basic Network Samples
Scene Navigation
NetWorker
Master Server
Web Server
Netcoding Design Patterns
Troubleshooting
Miscellaneous
Forge Networking Alloy
Steamworks
Clone this wiki locally