1

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());
            }
        }
user35443
  • 6,309
  • 12
  • 52
  • 75
Emaad Ali
  • 1,483
  • 5
  • 19
  • 42
  • Uhm... don't forcibly close the connection on the remote host? – dtb Aug 02 '10 at 15:54
  • Are you the only client accessing the server? Could it be that the server has exceeded the number of connections allowed? If you have access to the server code, do you know if it's getting called? – David Hoerster Aug 02 '10 at 15:57
  • there other clients are available who can access server. – Emaad Ali Aug 02 '10 at 16:04
  • In your `SendCallBack`, you commented out the call the `EndSend()`. I don’t think that’s a good idea. – Timwi Aug 02 '10 at 16:20

2 Answers2

5

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, then EndReceive() will succeed, but if that “something” is that the server has closed the connection, your callback will still be invoked, and then EndReceive() will throw the relevant SocketException. 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...)

Timwi
  • 65,159
  • 33
  • 165
  • 230
0

Based on your error, I'm not sure the problem is with your code, it may be on the server. Beyond adding some state checking to validate that handler.EndReceive(ar) will return something useful, you'll probably need to check the server itself (or ask the people who maintain it to do so) to see why it's closing the connection on you.

In the end, the problem code could be in your initial code, instead of in this piece: say, if the intial call to the server is too long and causes a timeout or deadlock.

AllenG
  • 8,112
  • 29
  • 40