Emaad Ali
Emaad Ali

Reputation: 1501

C# An existing connection was forcibly closed by the remote host: socket programming

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());
            }
        }

Upvotes: 1

Views: 31519

Answers (2)

Timwi
Timwi

Reputation: 66573

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...)

Upvotes: 5

AllenG
AllenG

Reputation: 8190

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.

Upvotes: 0

Related Questions