Binary stream 'NN' does not contain a valid BinaryHeader - c#

I am passing user defined classes over sockets. The SendObject code is below. It works on my local machine, but when I publish to the WebServer which is then communicating with the App Server on my own machine it fails.
public bool SendObject(Object obj, ref string sErrMsg)
{
try
{
MemoryStream ms = new MemoryStream();
BinaryFormatter bf1 = new BinaryFormatter();
bf1.Serialize(ms, obj);
byte[] byArr = ms.ToArray();
int len = byArr.Length;
m_socClient.Send(byArr);
return true;
}
catch (Exception e)
{
sErrMsg = "SendObject Error: " + e.Message;
return false;
}
}
I can do this fine if it is one class in my tools project and the other class about UserData just doesn't want to know. Frustrating!
Ohh. I think it's because the UserData class has a DataSet inside it. Funnily enough I have seen this work, but then after 1 request it goes loopy and I can't get it to work again.
Anyone know why this might be? I have looked at comparing the dlls to make sure they are the same on the WebServer and on my local machine and they look to be so as I have turned on versioning in the AssemblyInfo.cs to double check.
Possible causes are invalid stream or object version change between serialization and deserialization.
Edit:
Ok it seems that the problem is with size. If I keep it under 1024 byes ( I am guessing here) it works on the web server and doesn't if it has a DataSet inside it.k In fact this is so puzzling I converted the DataSet to a string using ds.GetXml() and this also causes it to blow up. :( So it seems that across the network something with my sockets is wrong and doesn't want to read in the data.

This is solved by a better question I have posted here :
Sending large serialized objects over sockets is failing only when trying to grow the byte Array, but ok when using a massive byte array
Obviously I had a static buffer that I had lifted from some toy example, and then when I started passing populated datasets they were too large. The answers to some dynamic buffer problems I was having cover this too.

Related

Random error Memory stream is not expandable

I was updating word document content using following code which was randomly throwing error Memory stream is not expandable:
MemoryStream TemplateFileMS = new MemoryStream(fileBytes);
using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(TemplateFileMS, true))
//...
// some code
//...
wordDoc.MainDocumentPart.Document.Save(); // Exception here
After changing the code to below, the error is not occurring.
MemoryStream TemplateFileMS = new MemoryStream(0);
TemplateFileMS.Write(fileBytes, 0, fileBytes.Length);
So I am able to fix the issue. But I didn't see the above error in my dev environment on Azure App Service but in the production Azure App Service I was getting the Memory is not expandable error randomly.
Is it related to the number of bytes/updates that is making difference here? e.g. while testing I make only few updates but in some scenarios there are more updates which requires extra memory than the set capacity.
I tried adding more updates to the document but I was not able to reproduce this error with previous code.
Thank you!
Normally, you'd only initialize a MemoryStream from a byte[] to read values from an existing buffer. But you are writing to the stream. That means you either need to let the MemoryStream manage the buffers itself (by not giving it one), or the buffer you give it needs to be big enough. In most cases the first option is simpler. It is complaining because you have given it a buffer that turned out to be too small, but it can't resize it because you defined the buffer externally (rather than letting the MemoryStream have control).

Before completing the analysis was detected ending stream

It's me again and I have another problem. Somewhere, I've found following code:
private T DeepDeserialize<T>(string fileName)
{
T returnValue;
using (FileStream str = new FileStream(fileName, FileMode.Open))
{
BinaryFormatter binaryFormatter = new BinaryFormatter();
returnValue = (T)binaryFormatter.Deserialize(str);
}
return returnValue;
}
I've modified some classes today and now, it always throws an error, which could be translated like this: Before completing the analysis was detected ending stream (I don't know the right translation, the error message is in my language, not in English)
I've tried to insert str.Position = 0; between these two lines in using, which I've found somewhere here, but it doesn't help.
Can someone help me to make it work again? I have no ideas what to do...
You have changed the binary layout of your files but most likely trying to deserialize old files. This is not gonna work. You have to serialize new versions first.
P.S. If you would consider versioning and custom formatter at early stages, you might be able to deserialize old data with new classes, depending on how drastic was your change

C# Networkstream BeginRead How to obtain buffer length/size?

I have a problem to obtain the right buffer size of my application.
What i read from the site about specifying the buffer size is normally declared before reading.
byte[] buffer = new byte[2000];
And then using to get the result.
However, this method will stop once the received data contains '00', but my return code contains something like this... 5300000002000000EF0000000A00. and the length is not fixed, can be this short until 400 bytes
So the problems comes, if i define a prefixed length like above, eg 2000, the return value is
5300000002000000EF0000000A000000000000000000000000000000000000000000000000000..........
thus making me unable to split the bytes to the correct amount.
Can any1 show me how to obtain the actual received data size from networkstream or any method/cheat to get what i need?
Thanks in advance.
Network streams have no length.
Unfortunately, your question is light on detail, so it's hard to offer specific advice. But you have a couple of options:
If the high-level protocol being used here offers a way to know the length of the data that will be sent, use that. This could be as simple as the remote host sending the byte count before the rest of the data, or some command you could send to the remote host to query the length of the data. Without knowing what high-level protocol you're using, it's not possible to say whether this is even an option or not.
Write the incoming data into a MemoryStream object. This would always work, whether or not the high-level protocol offers a way to know in advance how much data to expect. Note that if it doesn't, then you will simply have to receive data until the end of the network stream.
The latter option looks something like this:
MemoryStream outputStream = new MemoryStream();
int readByteCount;
byte[] rgb = new byte[1024]; // can be any size
while ((readByteCount = inputStream.Read(rgb, 0, rgb.Length)) > 0)
{
outputStream.Write(rgb, 0, readByteCount);
}
return outputStream.ToArray();
This assumes you have a network stream named "inputStream".
I show the above mainly because it illustrates the more general practice of reading from a network stream in pieces and then storing the result elsewhere. Also, it is easily adapted to directly reading from a socket instance (you didn't mention what you're actually using for network I/O).
However, if you are actually using a Stream object for your network I/O, then as of .NET 4.0, there has been a more convenient way to write the above:
MemoryStream outputStream = new MemoryStream();
inputStream.CopyTo(outputStream);
return outputStream.ToArray();

Sending object from Android Client App to C# Server App

Java Code:
public class EMessage implements Serializable
{
private Bitmap image;
private String type;
EMessage()
{}
}
...
EMessage eMessage=new EMessage();
outToServer = new DataOutputStream(clientSocket.getOutputStream());
objectOutputStream=new ObjectOutputStream(outToServer);
objectOutputStream.writeObject(eMessage);
C# Code:
[Serializable]
class EMessage
{
private Bitmap image;
private String type;
EMessage()
{ }
}
client = server.AcceptTcpClient();
Connected = client.Connected;
ns = client.GetStream();
IFormatter formatter = new
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
EMessage recievedmsg = (EMessage)formatter.Deserialize(ns);
When I send an object from Android Client App (java coded) and I recieve the object in C# Server App but with an Exception.
"The Input Stream is not a valid binary format. The Starting Content(in bytes) are:
00-05-73-72-00-1D-63-6F-6D-2E etc";
Please suggest any simple solution. My project isn't that much complex. I just need to send an EMessage object.
Serialization formats are specific to the platforms, and Java and .NET serialization aren't compatible with each other. Use JSON instead (and it's easier to debug as well).
Why not use SOAP, here's an article on exactly what you're doing (android to .net)
http://www.codeproject.com/Articles/29305/Consuming-NET-Web-Services-via-the-kSOAP-library
I suggest you drop the Serialization for the above mentioned reasons (Java serialization being different from C# serialization), and transfer your data between your Java and C# applications in plain byte arrays.
You can convert your Bitmap image to a byte array like so (taken from this post on SO):
Bitmap bmp = intent.getExtras().get("data");
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] byteArray = stream.toByteArray();
Of course you could change the CompressFormat if circumstances so require. After that, you could convert your type string to a byte array too, and add a null-terminator to the end of it.
Once you're there, you can send your type string first, and add the byte array of the bitmap after it. On the C# end, you could read the incoming data until you reach the 0 terminator, at which point you'll know you've read the string portion of your EMessage object, and then read the rest of the bytes you've sent over and parse them into a Bitmap object.
That way you'll be sure that between your Java and C# implementations, you won't run into any compatibility issues. It may require a bit more code and a little more understanding to do, but it's far more reliable than serializing between two languages.

How do I seamlessly compress the data I post to a form using C# and IIS?

I have to interface with a slightly archaic system that doesn't use webservices. In order to send data to this system, I need to post an XML document into a form on the other system's website. This XML document can get very large so I would like to compress it.
The other system sits on IIS and I use C# my end. I could of course implement something that compresses the data before posting it, but that requires the other system to change so it can decompress the data. I would like to avoid changing the other system as I don't own it.
I have heard vague things about enabling compression / http 1.1 in IIS and the browser but I have no idea how to translate that to my program. Basically, is there some property I can set in my program that will make my program automatically compress the data that it is sending to IIS and for IIS to seamlessly decompress it so the receiving app doesn't even know the difference?
Here is some sample code to show roughly what I am doing;
private static void demo()
{
Stream myRequestStream = null;
Stream myResponseStream = null;
HttpWebRequest myWebRequest = (HttpWebRequest)System.Net
.WebRequest.Create("http://example.com");
byte[] bytMessage = null;
bytMessage = Encoding.ASCII.GetBytes("data=xyz");
myWebRequest.ContentLength = bytMessage.Length;
myWebRequest.Method = "POST";
// Set the content type as form so that the data
// will be posted as form
myWebRequest.ContentType = "application/x-www-form-urlencoded";
//Get Stream object
myRequestStream = myWebRequest.GetRequestStream();
//Writes a sequence of bytes to the current stream
myRequestStream.Write(bytMessage, 0, bytMessage.Length);
//Close stream
myRequestStream.Close();
WebResponse myWebResponse = myWebRequest.GetResponse();
myResponseStream = myWebResponse.GetResponseStream();
}
"data=xyz" will actually be "data=[a several MB XML document]".
I am aware that this question may ultimately fall under the non-programming banner if this is achievable through non-programmatic means so apologies in advance.
I see no way to compress the data on one side and receiving them uncompressed on the other side without actively uncompressing the data..
No idea if this will work since all of the examples I could find were for download, but you could try using gzip to compress the data, then set the Content-Encoding header on the outgoing message to gzip. I believe that the Length should be the length of the zipped message, although you may want to play with making it the length of the unencoded message if that doesn't work.
Good luck.
EDIT I think the issue is whether the ISAPI filter that supports compression is ever/always/configurably invoked on upload. I couldn't find an answer to that so I suspect that the answer is never, but you won't know until you try (or find the answer that eluded me).

Categories

Resources