Simple situation:
The client on a Socket sends a pieces(e.g., 256 byte) of the file (data) in the format byte []to the server. The server receives the data asynchronously.
How to determine when a file (data) is transmitted completely? (Server-side)
Here’s the code on server-side responsible for receiving data
public static void ReadCallback(IAsyncResult ar)
{
String content = String.Empty;
// Retrieve the state object and the handler socket
// from the asynchronous state object.
StateObject state = (StateObject)ar.AsyncState;
Socket handler = state.workSocket;
// Read data from the client socket.
int bytesRead = handler.EndReceive(ar);
if (bytesRead > 0)
{
BinaryWriter writer = new BinaryWriter(File.Open(@"D:\test.png", FileMode.Append));
writer.Write(state.buffer, 0, bytesRead);
writer.Close();
// All the data has been read from the
// client. Display it on the console.
Console.WriteLine("Read {0} bytes from socket!",
bytesRead);
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReadCallback), state);
}
}
Is there a method that allows to make the some following?
if (bytesRead > 0)
{
....
if(state.buffer!=end of receive)
{
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReadCallback), state);
}
}
Or, I may to try add some information to the this byte[] object (e.g., some string with <EOF> tag)
but I must to analyse this info on each step.
May I do this check more simple and how? Or use another way …
The only way to do it is to sent a header (of specific size) in front of every message. So, the each message should consist of header and body. The data stream should look like this:
[HEADER][BODY][HEADER][SOME BIGGER BODY][HEADER][SOME EXTRA BIG BODY]
As I said, the header should be of specific size and should contain some custom service fields inlcuding the size of the message’s body in bytes. In your case the header could contain only body size, i.e. int value (4 bytes). The receive process should look like this:
I know, it may seem complicated for you, but it is the common way to do it. But you can simplify the code by using Rx library. After implementing some extensions methods for socket (WhenReadExact, the implementation could easily be found over Internet, for example here), the code will look like this: