I am working with sockets. Here are my codes (the description of problem is further):
Client side:
public void ReadCallback(IAsyncResult ar)
{
int fileNameLen = 1;
String content = String.Empty;
StateObject state = (StateObject)ar.AsyncState;
Socket handler = state.workSocket;
int bytesRead = handler.EndReceive(ar);
if (bytesRead > 0)
{
if (flag == 0)
{
fileNameLen = BitConverter.ToInt32(state.buffer, 0);
string fileName = Encoding.UTF8.GetString(state.buffer, 4, fileNameLen);
receivedPath = mypath + @"XML\";
if (!Directory.Exists(receivedPath))
{
Directory.CreateDirectory(receivedPath);
}
receivedPath = receivedPath + fileName;
flag++;
}
if (flag >= 1)
{
BinaryWriter writer = new BinaryWriter(File.Open(receivedPath, FileMode.Append));
if (flag == 1)
{
writer.Write(state.buffer, 4 + fileNameLen, bytesRead - (4 + fileNameLen));
flag++;
}
else
writer.Write(state.buffer, 0, bytesRead);
writer.Close();
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReadCallback), state);
}
}
else
{
// Invoke(new MyDelegate(LabelWriter));
}
}
I get error on this line: int bytesRead = handler.EndReceive(ar);
How can I avoid this error?: An existing connection was forcibly closed by the remote host
Server side:
public void ReadCallback(IAsyncResult ar)
{
try
{
int fileNameLen = 1;
String content = String.Empty;
StateObject state = (StateObject)ar.AsyncState;
Socket handler = state.workSocket;
string[] str = new string[2];
str = handler.RemoteEndPoint.ToString().Split(':');
IP = str[0].ToString();
int bytesRead = handler.EndReceive(ar);
if (bytesRead > 0)
{
if (flag == 0)
{
fileNameLen = BitConverter.ToInt32(state.buffer, 0);
string fileName = Encoding.UTF8.GetString(state.buffer, 4, fileNameLen);
string[] getIP = new string[3];
getIP = fileName.Split('_');
#region Send Files in HandHeld
#region GetLoginFile
if (getIP[1].ToString().Equals("GetLoginFile"))
{
string getDirectory = @"Send_Hand_Held_Files\" + DateTime.Today.ToString("dd-MM-yyyy") + "\\" + getIP[0].ToString() + "\\XML";
string strmyFile = getDirectory + "\\Login.xml";
char[] delimiter = splitter.ToCharArray();
split = strmyFile.Split(delimiter);
int limit = split.Length;
fName = split[limit - 1].ToString();
byte[] LoginfileName = Encoding.UTF8.GetBytes(fName); //file name
byte[] fileData = File.ReadAllBytes(strmyFile);
byte[] LoginfileNameLen = BitConverter.GetBytes(LoginfileName.Length); //lenght of file name
clientData = new byte[4 + LoginfileName.Length + fileData.Length];
LoginfileNameLen.CopyTo(clientData, 0);
LoginfileName.CopyTo(clientData, 4);
fileData.CopyTo(clientData, 4 + LoginfileName.Length);
handler.BeginSend(clientData, 0, clientData.Length, 0, new AsyncCallback(SendCallBack), handler);
//handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
//new AsyncCallback(ReadCallback), state);
return;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
//SendData(IP);
}
private static void SendCallBack(IAsyncResult ar)
{
try
{
// Retrieve the socket from the state object.
Socket client = (Socket)ar.AsyncState;
// Complete sending the data to the remote device.
// int bytesSent = client.EndSend(ar);
//Console.WriteLine("Sent {0} bytes to server.", bytesSent);
// Signal that all bytes have been sent.
allDone.Set();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
You are getting an exception from
handler.EndReceive(). While admittedly it is unclear why you’re receiving the specific exception you mentioned, when put into production this code will throw exceptions every time there is a network communication problem (which is common).Therefore, you should probably put a try/catch around the call to
EndReceive()anyway. Think about what your code would need to do whenever the connection fails or the server dies or whatever.Then you can start diagnosing specific problems. One important thing you haven’t specified: do you get this error only occasionally or do you reproducibly get it all the time? If it’s the former, then it might just be normal Internet connectivity fluctuations. Your software will have to be able to handle those. If it’s the latter, then I think it sounds like a problem on the server. When you call
BeginReceive(), your system will start waiting for something from the server; if that “something” is that it received data, thenEndReceive()will succeed, but if that “something” is that the server has closed the connection, your callback will still be invoked, and thenEndReceive()will throw the relevantSocketException. This is by design because there’s pretty much no other way to communicate to your code that the server has closed the connection.EDIT: Looks like your server code needs the same error handling: its call to
EndReceive()is equally prone to throwing an exception if the client closes the connection. (I know you have a try/catch around the whole big thing, but it outputs a MessageBox… that is not going to work well on a server, unless you want someone sitting there all the time clicking on all the OK buttons…)