Reputation: 125
I'm making a client-server application, but when I try to login it throws an OutOfMemoryException, here is my code server-side:
byte[] buffer = new byte[4];
requestCount = requestCount + 1;
NetworkStream networkStream = clientSocket.GetStream();
buffer = new byte[4];
int readBytes = networkStream.Read(buffer, 0, 4);
readBytes = networkStream.Read(buffer, 0, 4);
if (readBytes == 0)
break;
int MessageSize = BitConverter.ToInt32(buffer, 0);
byte[] bufferreader = new byte[MessageSize]; <- here the exception is thrown
readBytes = networkStream.Read(bufferreader, 0, MessageSize);
if (readBytes == 0)
break;
dataFromClient = Encoding.ASCII.GetString(bufferreader);
rCount = Convert.ToString(requestCount);
serverResponse = R.Respond(dataFromClient);
sendBytes = Encoding.ASCII.GetBytes(serverResponse);
networkStream.Write(sendBytes, 0, sendBytes.Length);
networkStream.Flush();
and here is my client-side code:
clientSocket.Connect("192.168.1.100", 666);
SHA512Managed S = new SHA512Managed();
byte[] result = S.ComputeHash(Encoding.UTF8.GetBytes(password));
string epassword = Convert.ToBase64String(result);
try
{
byte[] buffer = new byte[4];
NetworkStream serverStream = clientSocket.GetStream();
byte[] outStream = Encoding.ASCII.GetBytes("authenticate|" + user + "$");
buffer = new byte[4];
buffer = BitConverter.GetBytes(outStream.Length);
serverStream.Write(buffer, 0, 4);
serverStream.Flush();
serverStream.Write(outStream, 0, outStream.Length);
serverStream.Flush();
byte[] inStream = new byte[10025];
serverStream.Read(inStream, 0, (int)clientSocket.ReceiveBufferSize);
string returndata = Encoding.ASCII.GetString(inStream);
}
catch(Exception ex)
{
Toast.MakeText(l, ex.Message, ToastLength.Long).Show();
}
Toast.MakeText(l, "Logged In: " + epassword, ToastLength.Long).Show();
So basically the client first sends the length of the actual message to the server so it knows how much bytes it has to expect, but when i create a new buffer that will hold the message it throws the OutOfMemoryException,
Thanks in advance
Upvotes: 0
Views: 115
Reputation: 14700
The problem probably lies in how you read the header containing the message length:
buffer = new byte[4];
int readBytes = networkStream.Read(buffer, 0, 4);
readBytes = networkStream.Read(buffer, 0, 4);
What you're doing here is reading 4 bytes off the stream into a buffer, and then reading 4 bytes again, overriding the previous buffer. This doesn't match the client sending code you have below, where the header is sent in the first 4 bytes. So what happens is that you get the message size, override it with the first 4 bytes of the actual payload, and then try to allocate a buffer based on those 4 arbitrary bytes.
Remove the second Read call, and it should be fine.
Generally speaking, though, you're doing a lot of work that the framework can already do for you. You can create a StreamWriter
to manage all your reads for you, without bothering with sending the message size as a "header":
NetworkStream networkStream = clientSocket.GetStream();
StreamReader reader = new StreamReader(networkStream, Encoding.ASCII)
dataFromClient = reader.ReadToEnd();
(And the corresponding StreamWriter
calls, of course)
Upvotes: 1