Application sometimes transfer file from client to server and sometimes not,
because connection betwenn client and server closed Abrupt.
I cannot understand why connection between client and server is closed while i cannot closed the connection until a single block
tranfered to server.
my client i.e. FileTransfer Application work in this manner
-----------------------------------------------------------
- define a bufferSize of type int to read block of data from file
- sendFile() function receive a file name like "E:/UplodingFile/abc.doc" or some other file i want to transfer
- read file using BinaryReader class of .Net
- create a byte array "bSentData" of size either file content length or buffer size whichever is less
- now sundFile() function goes into while loop and continue till the length of the file read.
- in the while loop, read block of data into bSentData byte array
- convert bSentData to Base64String, this is because this is my test application, and when this code runiing smoothly i incoroporate this to my office development library .
- append other necessary information to a StringBuilder variable
- now instatiate a socket object and call socket.BeginConnect for connection to server application with delegate aynccallback function
- using the ManualResetEvent ConnectDone, set ConnectDone.WaitOne();
- in asynccallback delegate function "onConnectedToSerever", call EndConnect. and set ConnectDone.Set() that a connection has been made
- now get total length of data to be sent to server
- send size information to server and using BeginSend
- wait for receiving response from server that server receive the data size.
- send actual data to server using BeginSend
- wait for response from server that server receive data.
- after calling seting ConnectDone.WaitOne() at step 10, increase block counter and check either socket connected to server or not if socket connected to server close connection to server
- repeat step 6 to 17 until complete file is tranfered to server.
Server FileReceiver Application work in this manner
----------------------------------------------------
- Server start listening on specific port.
- waiting for connection from client calling BeginAccept
- when a request arrive for establishing a connection, establishing a connection to client by calling EndAccept
- call function WaitForData, create stateobject class object, function waiting for receiving data from client using BeginReceive
- BeginReceive callback function OnReceive, receive request by calling EndReceive,
- OnReceive function add bytes receive to stateobject class variable BytesReceived
- onreceive function verify that thata stateobject.messgaesize variable of stateobject call is -1, meaning that client now sending data size to server.
- if bytesreceived == 4, we have receive the size of the data and read its value.
- send response to clinet waiting from server that server has received the data size.
- create stateobject byte array variable buffer to data size received.
- call beginReceive again from OnReceive function to read actual data from client untill we read all data i.e. stateobject.bytesreceived = stateobject.messagesize
- when we received complete data from client,send a response to client that we have received complete data and process our data
Client Code
-----------
Expand|Select|Wrap|Line Numbers
- class FileHandling
- {
- // ManualResetEvent instances signal completion.
- private static ManualResetEvent connectDone =
- new ManualResetEvent(false);
- private static ManualResetEvent sendSizeDone =
- new ManualResetEvent(false);
- private static ManualResetEvent sendDataDone =
- new ManualResetEvent(false);
- private static ManualResetEvent receiveSizeDone =
- new ManualResetEvent(false);
- private static ManualResetEvent receiveDataDone =
- new ManualResetEvent(false);
- // Get the remote IP address
- private static IPAddress ip = IPAddress.Parse("127.0.0.1"); //"10.0.0.9"
- // Create the end point
- private static IPEndPoint ipEnd = new IPEndPoint(ip, 1200);
- public void SendLargeFile(string sFileName)
- {
- string sRequest = string.Empty;
- try
- {
- if (sFileName.Length < 1)
- {
- MessageBox.Show("No file selected");
- return;
- }
- SendFile(sFileName);
- MessageBox.Show("File Transfered");
- }
- catch (Exception objEx)
- {
- MessageBox.Show(objEx.Message);
- }
- }
- #region SendFile
- private void SendFile(string sSentFileName)
- {
- Socket m_clientSocket = null;
- string sAppendRequest = "",
- sCurrentFileName = string.Empty,
- sBufferData = string.Empty;
- int iTotalSentDataSize = 0;
- int iTotalSentDataSlot = 0;
- byte[] bSentData = null;
- BinaryReader ObjBinReader = null;
- byte[] sizeinfo = new byte[4];
- byte[] dataBuffer = null;
- try
- {
- int iBufferSize = 20480;
- sCurrentFileName = sSentFileName.Replace(@"\", "/");
- ObjBinReader = new BinaryReader(File.Open(sCurrentFileName, FileMode.Open));
- while (sCurrentFileName.IndexOf("/") != -1)
- {
- sCurrentFileName = sCurrentFileName.Substring(sCurrentFileName.IndexOf("/") + 1);
- }
- if (ObjBinReader.BaseStream.Length < iBufferSize)
- {
- bSentData = new byte[ObjBinReader.BaseStream.Length];
- iBufferSize = (int)ObjBinReader.BaseStream.Length;
- }
- else
- {
- bSentData = new byte[iBufferSize];
- }
- while ((iBufferSize * iTotalSentDataSlot) < ObjBinReader.BaseStream.Length)
- {
- sAppendRequest = "";
- if (iBufferSize * (iTotalSentDataSlot + 1) < ObjBinReader.BaseStream.Length)
- {
- ObjBinReader.Read(bSentData, 0, iBufferSize);
- sBufferData = Convert.ToBase64String(bSentData);
- iTotalSentDataSize += iBufferSize;
- sAppendRequest = (iTotalSentDataSlot + 1).ToString().PadRight(20, ' '); // 0-19
- sAppendRequest += (sBufferData.Length).ToString().PadRight(20, ' '); // 20-39
- sAppendRequest += (iTotalSentDataSize).ToString().PadRight(20, ' '); // 40 - 59
- sAppendRequest += (sCurrentFileName + "." + iTotalSentDataSlot).ToString().PadRight(100, ' '); // 60 - 159
- sAppendRequest += sBufferData.ToString().PadRight(27400, ' '); // 160 - 27559
- }
- else
- {
- int iRemLen = (int)ObjBinReader.BaseStream.Length - iBufferSize * iTotalSentDataSlot;
- bSentData = new byte[iRemLen];
- ObjBinReader.Read(bSentData, 0, iRemLen);
- sBufferData = Convert.ToBase64String(bSentData);
- iTotalSentDataSize += iRemLen;
- sAppendRequest = (iTotalSentDataSlot + 1).ToString().PadRight(20, ' ');
- sAppendRequest += (sBufferData.Length).ToString().PadRight(20, ' ');
- sAppendRequest += iTotalSentDataSize.ToString().PadRight(20, ' ');
- sAppendRequest += (sCurrentFileName + "." + iTotalSentDataSlot + ".E").ToString().PadRight(100, ' ');
- sAppendRequest += sBufferData.ToString().PadRight(27400, ' ');
- }
- m_clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
- m_clientSocket.NoDelay = true;
- StateObject stateObject = new StateObject(m_clientSocket, sAppendRequest);
- // Connect to the remote host
- m_clientSocket.BeginConnect(ipEnd, new AsyncCallback(onConnectedToSerever), stateObject);
- // wait for the connection to be made
- connectDone.WaitOn();
- iTotalSentDataSlot++;
- if (m_clientSocket.Connected)
- {
- m_clientSocket.Shutdown(SocketShutdown.Both);
- m_clientSocket.Close();
- }
- }
- }
- catch (Exception objEx)
- {
- MessageBox.Show("SendFile : " +objEx.Message + "; Stack Trace :" + objEx.StackTrace);
- }
- finally
- {
- if (ObjBinReader != null)
- ObjBinReader.Close();
- }
- }
- #endregion
- private void onConnectedToSerever(IAsyncResult iar)
- {
- try
- {
- StateObject stateObject = (StateObject)iar.AsyncState;
- stateObject.workerSocket.EndConnect(iar);
- // Signal that the connection has been made
- connectDone.Set();
- stateObject.dataBuffer = Encoding.ASCII.GetBytes(stateObject.sMessage);
- byte[] sizeinfo = new byte[4];
- sizeinfo[0] = (byte)stateObject.dataBuffer.Length;
- sizeinfo[1] = (byte)(stateObject.dataBuffer.Length >> 8);
- sizeinfo[2] = (byte)(stateObject.dataBuffer.Length >> 16);
- sizeinfo[3] = (byte)(stateObject.dataBuffer.Length >> 24);
- SendDataSize(stateObject, sizeinfo);
- sendSizeDone.WaitOne();
- ReceiveDataSize(stateObject);
- receiveSizeDone.WaitOne();
- SendData(stateObject, stateObject.dataBuffer);
- sendDataDone.WaitOne();
- ReceiveData(stateObject);
- receiveDataDone.WaitOne();
- }
- catch (Exception objEx)
- {
- MessageBox.Show("OnConnectedToServer : " + objEx.Message + "; Stack Trace :" + objEx.StackTrace);
- }
- }
- private void SendData(StateObject stateObject, byte[] data)
- {
- try
- {
- stateObject.workerSocket.BeginSend(data, 0, data.Length, SocketFlags.None, new AsyncCallback(OnSendToSever), stateObject);
- }
- catch (Exception objEx)
- {
- MessageBox.Show("SendData : " + objEx.Message + "; Stack Trace :" + objEx.StackTrace);
- }
- }
- private void SendDataSize(StateObject stateObject, byte[] data)
- {
- try
- {
- stateObject.workerSocket.BeginSend(data, 0, data.Length, SocketFlags.None, new AsyncCallback(OnSizeSendToSever), stateObject);
- }
- catch (Exception objEx)
- {
- MessageBox.Show("SendDataSize : " + objEx.Message + "; Stack Trace :" + objEx.StackTrace);
- }
- }
- private void ReceiveDataSize(StateObject stateObject)
- {
- try
- {
- StateObject receiveState = new StateObject(stateObject.workerSocket);
- receiveState.workerSocket.BeginReceive(receiveState.dataBuffer, 0, receiveState.dataBuffer.Length, SocketFlags.None, new AsyncCallback(OnSizeReceiveFromServer), receiveState);
- }
- catch (Exception objEx)
- {
- MessageBox.Show("ReceiveDataSize : " + objEx.Message + "; Stack Trace :" + objEx.StackTrace);
- }
- finally
- {
- }
- }
- private void ReceiveData(StateObject stateObject )
- {
- try
- {
- StateObject receiveState = new StateObject(stateObject.workerSocket);
- receiveState.workerSocket.BeginReceive(receiveState.dataBuffer, 0, receiveState.dataBuffer.Length, SocketFlags.None, new AsyncCallback(OnDataReceiveFromServer), receiveState);
- }
- catch (Exception objEx)
- {
- MessageBox.Show("ReceiveData : " + objEx.Message + "; Stack Trace :" + objEx.StackTrace);
- }
- finally
- {
- }
- }
- private void OnSizeSendToSever(IAsyncResult m_asyncResult)
- {
- try
- {
- StateObject stateObject = (StateObject)m_asyncResult.AsyncState;
- int iBytesSend = stateObject.workerSocket.EndSend(m_asyncResult);
- // Signal that all bytes have been sent.
- sendSizeDone.Set();
- }
- catch (Exception objEx)
- {
- MessageBox.Show("OnSizeSendToSever : " + objEx.Message + "; Stack Trace :" + objEx.StackTrace);
- }
- }
- private void OnSendToSever(IAsyncResult m_asyncResult)
- {
- try
- {
- StateObject stateObject = (StateObject)m_asyncResult.AsyncState;
- int iBytesSend = stateObject.workerSocket.EndSend(m_asyncResult);
- // Signal that all bytes have been sent.
- sendDataDone.Set();
- }
- catch (Exception objEx)
- {
- MessageBox.Show("OnSendToServer : " + objEx.Message + "; Stack Trace :" + objEx.StackTrace);
- }
- }
- private void OnSizeReceiveFromServer(IAsyncResult iar)
- {
- try
- {
- StateObject state = (StateObject) iar.AsyncState;
- Socket client = state.workerSocket;
- int bytesRead = client.EndReceive(iar);
- // There might be more data, so store the data received so far.
- state.sMessage += Encoding.ASCII.GetString(state.dataBuffer, 0, bytesRead);
- // Signal that all bytes have been received.
- receiveSizeDone.Set();
- }
- catch(SocketException objEx)
- {
- MessageBox.Show("OnSizeReceiveFromServer :" + objEx.Message + "; Stack Trace :" + objEx.StackTrace + " ErrorCode : " + objEx.ErrorCode + " Source : " + objEx.Source);
- }
- catch (Exception objEx)
- {
- MessageBox.Show("OnSizeReceiveFromServer :" + objEx.Message + "; Stack Trace :" + objEx.StackTrace);
- }
- }
- private void OnDataReceiveFromServer(IAsyncResult iar)
- {
- try
- {
- StateObject state = (StateObject)iar.AsyncState;
- Socket client = state.workerSocket;
- int bytesRead = client.EndReceive(iar);
- // There might be more data, so store the data received so far.
- state.sMessage += Encoding.ASCII.GetString(state.dataBuffer, 0, bytesRead);
- // Signal that all bytes have been received.
- receiveDataDone.Set();
- }
- catch (SocketException objEx)
- {
- MessageBox.Show("OnDataReceiveFromServer :" + objEx.Message + "; Stack Trace :" + objEx.StackTrace + " ErrorCode : " + objEx.ErrorCode + " Source : " + objEx.Source);
- }
- catch (Exception objEx)
- {
- MessageBox.Show("OnDataReceiveFromServer :" + objEx.Message + "; Stack Trace :" + objEx.StackTrace);
- }
- }
- }
- #region Class StateObject to receive data from connected remote server
- public class StateObject
- {
- public StateObject(Socket workerSocket)
- {
- this.workerSocket = workerSocket;
- this.sMessage = "";
- }
- public StateObject(Socket workerSocket, string sMessage)
- {
- this.workerSocket = workerSocket;
- this.sMessage = sMessage;
- }
- // Received Data buffer Size
- public const int iBufferSize = 50000;
- // Received Data Buffer
- public byte[] dataBuffer = new byte[iBufferSize];
- //sending message to server
- public string sMessage = string.Empty;
- // Client Socket
- public System.Net.Sockets.Socket workerSocket;
- }
- #endregion
Server Code
------------
Expand|Select|Wrap|Line Numbers
- public partial class Form1 : Form
- {
- // Thread signal.
- public static ManualResetEvent allDone = new ManualResetEvent(false);
- public delegate void UpdateMessageBoxDelegate(string sText);
- public Form1()
- {
- InitializeComponent();
- }
- private void Start_Click(object sender, EventArgs e)
- {
- try
- {
- //create the listening socket...
- Socket m_socListener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
- IPEndPoint ipLocal = new IPEndPoint(IPAddress.Any, 1200);
- //bind to local IP Address...
- m_socListener.Bind(ipLocal);
- //start listening...
- m_socListener.Listen(500);
- richTextBox1.Text = "Start Listening \n";
- label1.Text = "Server is in listening mode";
- Start.Enabled = false;
- while (true)
- {
- // Set the event to nonsignaled state.
- allDone.Reset();
- m_socListener.BeginAccept(new AsyncCallback(OnClientConnect), m_socListener);
- // Wait until a connection is made before continuing.
- allDone.WaitOne();
- }
- }
- catch (Exception ObjEx)
- {
- // Create Error Log
- MessageBox.Show("Start_Click :" + ObjEx.Message);
- }
- }
- public void OnClientConnect(IAsyncResult asyn)
- {
- // Signal the main thread to continue.
- allDone.Set();
- try
- {
- Socket listner = (Socket)asyn.AsyncState ;
- Socket workerSocket = listner.EndAccept(asyn);
- WaitForData(workerSocket);
- }
- catch (ObjectDisposedException ObjEx)
- {
- MessageBox.Show("OnClientConnect_ObjectDisposedException :" + ObjEx.Message + "; Stack Trace :" + ObjEx.StackTrace);
- }
- catch (SocketException ObjEx)
- {
- MessageBox.Show("OnClientConnect_SocketException:" + ObjEx.Message + "; Stack Trace :" + ObjEx.StackTrace);
- }
- }
- #region WaitForData
- public void WaitForData(System.Net.Sockets.Socket workerSocket)
- {
- try
- {
- StateObject stateObject = new StateObject(workerSocket);
- // now start to listen for any data...
- workerSocket.BeginReceive(stateObject.buffer,
- 0,
- stateObject.buffer.Length,
- SocketFlags.None,
- new AsyncCallback(OnDataReceived),
- stateObject);
- }
- catch (SocketException ObjEx)
- {
- // Create Err Log
- MessageBox.Show("WaitForData:" + ObjEx.Message + "; Stack Trace :" + ObjEx.StackTrace);
- }
- }
- #endregion
- #region OnDataReceived
- public void OnDataReceived(IAsyncResult asyn)
- {
- try
- {
- StateObject stateObject = asyn.AsyncState as StateObject;
- Socket handler = stateObject.workerSocket;
- int iCount = handler.EndReceive(asyn);
- stateObject.bytesReceived += iCount;
- if (stateObject.messageSize == -1) // we still reding the size of the message
- {
- if (iCount == 0)
- {
- MessageBox.Show("The remote peer closed the connection while reding the message size");
- throw new ProtocolViolationException("The remote peer closed the connection while reding the message size");
- }
- if (stateObject.bytesReceived == 4) // we are reding size of the data
- {
- //read size of the message
- stateObject.messageSize = BitConverter.ToInt32(stateObject.buffer, 0);
- //Send confirmation to client that server has received message size
- byte[] respond = Encoding.ASCII.GetBytes("Ok : received size of the data");
- handler.BeginSend(respond,
- 0,
- respond.Length,
- SocketFlags.None,
- new AsyncCallback(OnSendToClient),
- handler);
- if (stateObject.messageSize < 0)
- {
- MessageBox.Show("the remote peer send a negative size messsage");
- throw new ProtocolViolationException("the remote peer send a negative size messsage");
- }
- //only message size data be received
- stateObject.buffer = new byte[stateObject.messageSize];
- // reset the receiving bytes
- stateObject.bytesReceived = 0;
- }
- if (stateObject.messageSize != 0)
- {
- // we need more data either message size information
- // or
- // it could be the message body
- // only time we need no data when message size =0
- stateObject.workerSocket.BeginReceive(stateObject.buffer,
- stateObject.bytesReceived,
- stateObject.buffer.Length - stateObject.bytesReceived,
- SocketFlags.None,
- new AsyncCallback(OnDataReceived),
- stateObject);
- }
- else
- {
- //we have received the zero size message
- MessageBox.Show("we have received the zero size message");
- //objState.Dispose();
- }
- }
- else // we are reading the body of the message
- {
- if (stateObject.bytesReceived == stateObject.messageSize) // we have received the entire message
- {
- // send confimation to cleint that server has received the entire message
- byte[] responde = Encoding.ASCII.GetBytes("Ok : received entire message");
- handler.BeginSend(responde,
- 0,
- responde.Length,
- SocketFlags.None,
- new AsyncCallback(OnSendToClient),
- handler);
- // call function that will read bytes from objstate.buffer
- if (ProcessData(Encoding.ASCII.GetString(stateObject.buffer)))
- {
- stateObject.Dispose();
- }
- }
- else // we need more data
- {
- if (iCount == 0)
- {
- MessageBox.Show("The remote peer closed the connection before the entire message was received");
- throw new ProtocolViolationException("The remote peer closed the connection before the entire message was received");
- }
- stateObject.workerSocket.BeginReceive(stateObject.buffer,
- stateObject.bytesReceived,
- stateObject.buffer.Length - stateObject.bytesReceived,
- SocketFlags.None,
- new AsyncCallback(OnDataReceived),
- stateObject);
- }
- }
- }
- catch (ObjectDisposedException objEx)
- {
- //System.Diagnostics.Debugger.Log(0, "1", "\nOnDataReceived: Socket has been closed\n");
- MessageBox.Show("OnDataReceived: Socket has been closed :ObjectDisposedException " + "; Stack Trace :" + objEx.StackTrace);
- }
- catch (SocketException ObjEx)
- {
- // Create Err Log
- //System.Diagnostics.Debugger.Log(0, "1", "\nOnDataReceived: Socket has been closed\n");
- MessageBox.Show("OnDataReceived: Socket has been closed :SocketException " + "; Stack Trace :" + ObjEx.StackTrace);
- }
- catch (Exception objex)
- {
- MessageBox.Show("OnDataReceived :"+ objex.Message + "; Stack Trace :" + objex.StackTrace + " Source : "+ objex.Source);
- }
- finally
- {
- string sfinally = "";
- }
- }
- #endregion
- private void OnSendToClient(IAsyncResult iar)
- {
- try
- {
- Socket socket = iar.AsyncState as Socket;
- int iBytesSend = socket.EndSend(iar);
- }
- catch (Exception objEx)
- {
- MessageBox.Show("OnsendToClient : Message : "+objEx.Message + "; Stack Trace : " + objEx.StackTrace + "; Source : " + objEx.Source );
- }
- }
- private bool ProcessData(string szData)
- {
- string sRequest = string.Empty, sBufferData = string.Empty;
- string sEndPart = string.Empty;
- string sOrgFile = string.Empty,
- sCurrentFileName,
- sNextFileName = string.Empty;
- bool status = false;
- int iTotalSentDataSize = 0;
- int iTotalSentDataSlot = 0;
- int iBufferSize = 0;
- short iCounter = 0;
- byte[] bBufferData = null;
- BinaryWriter ObjBinaryWriter = null;
- try
- {
- iTotalSentDataSlot = Convert.ToInt32(szData.Substring(0, 20));
- iBufferSize = Convert.ToInt32(szData.Substring(20, 20));
- iTotalSentDataSize = Convert.ToInt32(szData.Substring(40, 20));
- sCurrentFileName = szData.Substring(60, 100);
- sBufferData = szData.Substring(160, iBufferSize); //27400
- sOrgFile = sCurrentFileName.Substring(0, sCurrentFileName.LastIndexOf("."));
- sEndPart = sCurrentFileName.Substring(sCurrentFileName.LastIndexOf(".") + 1);
- sNextFileName = AppDomain.CurrentDomain.BaseDirectory + "/" + sCurrentFileName;
- if (File.Exists(sNextFileName))
- File.Delete(sNextFileName);
- File.WriteAllBytes(sNextFileName, Convert.FromBase64String(sBufferData));
- File.SetAttributes(sNextFileName, FileAttributes.Hidden);
- status = true;
- if (sEndPart.Trim() == "E")
- {
- sOrgFile = sOrgFile.Substring(0, sOrgFile.LastIndexOf("."));
- sEndPart = "0";
- sOrgFile = AppDomain.CurrentDomain.BaseDirectory + "/" + sOrgFile;
- if (File.Exists(sOrgFile))
- File.Delete(sOrgFile);
- ObjBinaryWriter = new BinaryWriter(File.Open(sOrgFile, FileMode.Append));
- bBufferData = new byte[ObjBinaryWriter.BaseStream.Length];
- iCounter = Convert.ToInt16(sEndPart);
- while (true)
- {
- sNextFileName = sOrgFile + "." + iCounter.ToString();
- if (File.Exists(sNextFileName + ".E"))
- {
- //Last slice
- bBufferData = File.ReadAllBytes(sNextFileName + ".E");
- ObjBinaryWriter.Write(bBufferData);
- File.Delete(sNextFileName + ".E");
- break;
- }
- else
- {
- bBufferData = File.ReadAllBytes(sNextFileName);
- ObjBinaryWriter.Write(bBufferData);
- File.Delete(sNextFileName);
- }
- iCounter++;
- }
- }
- }
- catch (Exception objEx)
- {
- status = false;
- }
- finally
- {
- if (ObjBinaryWriter != null)
- ObjBinaryWriter.Close();
- }
- return status;
- }
- private void UpdateText(string sMessage)
- {
- richTextBox1.Text += sMessage + "\n";
- }
- }
- // Class StateObject mantain state
- public class StateObject : IDisposable
- {
- public StateObject(Socket workerSocket)
- {
- this.workerSocket = workerSocket;
- buffer = new byte[4];
- bytesReceived = 0;
- messageSize = -1;
- }
- public void Dispose()
- {
- this.workerSocket = null;
- this.buffer = null;
- }
- // Client socket.
- public Socket workerSocket = null;
- // Receive buffer.
- public byte[] buffer ;
- public int bytesReceived;
- public int messageSize;
- }
i.e. from client to server, next I want to transfer file from server to client
thanks