[Mono-dev] .NET Remoting: Upload of a file from a Win32 MS .NET client to a Linux Mono .NET server.

Yngve Zackrisson yngve.zackrisson at mobila-kontoret.se
Fri Sep 2 04:30:22 EDT 2005


Hi there.

This is the first time I send a mail to this list.

I am currently trying to set up a .NET Remoting application.
For the communication I use HTTP with binary formating 
as a communication  channel.
I have got the application work with MS .NET Win32 on both 
the client and server side.

After some struggle (with configuration files and custom channel) 
I am now able to do remote invocations from my Win32 MS .NET client 
to my Linux (Fedora3) Mono .NET host (console) application.
All works well having primitive datatypes and DataSets as parameters 
and returns in the methods.

The problems (now) arise when i try to upload a zip file from 
the client to the server.
I use a parameter with a (File)Stream object to do "callbacks" 
to Read the file in blocks from the client into the server.
When calling the Read(buffer, 0, buffer.Length) method 
I get index out of range exception messages on my the Mono server.

Here is the code snippet for a simplified test example : 

public class RemoteObject : MarshalByRefObject
{

  ...

  // AFAIK not more than 350 Kb can be serialized in .NET.
  //private const int PORTION_SIZE = (256 * 1024);
  //private const int PORTION_SIZE = 1024;
  private const int PORTION_SIZE = 64;

  ...

  /// <summary>
  /// Method FileUpload to test the remoting.
  /// </summary>
  public bool FileUpload(Stream fileIn, long fileInLength)
  {
	bool returnValue = false;
	// Download large files in shunks.
	long bytesDownloadedIn = 0L;
	FileStream fileOut = new FileStream("FileOut.txt",
		FileMode.OpenOrCreate, FileAccess.Write);
	long bytesDownloadedOut = 0L;
	try 
	{
		for (bytesDownloadedIn = 0L; bytesDownloadedIn < 			fileInLength; )
		{
			// request the next portion
			int sizeToRead = (int)Math.Min(PORTION_SIZE, 				fileInLength -
bytesDownloadedIn);
			byte[] buffer = new byte[sizeToRead];
			fileIn.Read(buffer, 0, buffer.Length);	//<err>	 			// update counters
			bytesDownloadedIn += buffer.Length;
			// save it into the file
			fileOut.Write(buffer, 0, buffer.Length);
			fileOut.Flush();
			bytesDownloadedOut = bytesDownloadedIn;
		}
		returnValue = true;
	}
	catch (RemotingException remex) 
	{
		Console.WriteLine("FileUpload - RemotingException: " + remex.Message);
		returnValue = false;
	}
	catch (IOException ioex) 
	{
		Console.WriteLine("FileUpload - IOException: " + ioex.Message);
		returnValue = false;
	}
	catch (Exception ex) 
	{
		Console.WriteLine("FileUpload - Exception: " + ex.Message);
		returnValue = false;
	}
	finally 
	{
		fileOut.Close();
	}
	return returnValue;
  }

...

}

The error occur at <err> above.

The error message I get on the Mono server is:

EXCEPTION handling: IndexOutOfRangeException
EXCEPTION handling: IndexOutOfRangeException
FileUpload - Exception: Array index is out of range.



I have elaborated using FileStream and Stream, 
using different PORTION_SIZE and doing the 
buffer 1 byte longer than the sizeToRead.
The fileInLength is set at the client (to fileIn.Length) 
to avoid an extra roundtrip.

Can anyone advice me how I should do to upload 
a file from Win32 MS .NET to Linux Mono .NET.
The issue is critical to get my application to work on Mono.
Is there some other stream class I can use to transfer 
a file from the client to the server.

As an aside I also want to report back the progress 
of the file upload to the client.
I want to update a progressbar on my Win32 client. 
I have succeded to do that on my pure Win32 application, 
though some progressbar handling technique.
Am I expected to get any trouble using the ProgressBar 
indirectly as a method parameter?.

Regards 

Yngve Zackrisson













More information about the Mono-devel-list mailing list