C # Существующее соединение было принудительно закрыто удаленным хостом: программирование сокетов - PullRequest
1 голос
/ 02 августа 2010

Я работаю с розетками.Вот мои коды (описание проблемы далее):

Клиентская сторона :

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

Я получаю сообщение об ошибке в этой строке: int bytesRead = handler.EndReceive(ar);

Как мне избежать этой ошибки ?: An existing connection was forcibly closed by the remote host

На стороне сервера :

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

Ответы [ 2 ]

4 голосов
/ 02 августа 2010

Вы получаете исключение из handler.EndReceive().Хотя по общему признанию неясно , почему вы получаете конкретное исключение, которое вы упомянули, при вводе в действие этот код будет генерировать исключения каждый раз, когда возникает проблема сетевого взаимодействия (что является распространенным явлением).

Следовательно, вам, вероятно, следует все равно попытаться / поймать вызов на EndReceive().Подумайте о том, что будет делать ваш код в случае сбоя соединения, или когда сервер умирает или что-то в этом роде.

Тогда вы можете приступить к диагностике конкретных проблем.Одна важная вещь, которую вы не указали: вы получаете эту ошибку только изредка или воспроизводите ее постоянно ?Если это первое, то это могут быть просто колебания интернет-соединения.Ваше программное обеспечение должно быть в состоянии справиться с этим.Если это последнее, то я думаю, что это звучит как проблема на сервере.Когда вы звоните BeginReceive(), ваша система начнет ожидать чего-то от сервера;если это «что-то» означает, что оно получило данные, то EndReceive() выполнится успешно, но если это «что-то» означает, что сервер закрыл соединение , ваш обратный вызов все равно будет вызван, а затем EndReceive() выбросит соответствующий SocketException.Это сделано специально, потому что нет другого способа сообщить вашему коду, что сервер закрыл соединение.

РЕДАКТИРОВАТЬ: Похоже, ваш серверный код требует такой же обработки ошибок: еговызов EndReceive() в равной степени склонен вызывать исключение, если клиент закрывает соединение.(Я знаю, что у вас есть попытка / ловушка вокруг всей большой вещи, но она выводит MessageBox ..., который не будет хорошо работать на сервере, если вы не хотите, чтобы кто-то сидел там все время, нажимаяна все кнопки ОК ...)

0 голосов
/ 02 августа 2010

Судя по вашей ошибке, я не уверен, что проблема с вашим кодом, возможно, он на сервере.Помимо добавления некоторой проверки состояния для проверки того, что handler.EndReceive(ar) вернет что-то полезное, вам, вероятно, потребуется проверить сам сервер (или попросить людей, которые его поддерживают), чтобы понять, почему он закрывает соединение с вами.

В конце код проблемы мог быть в вашем исходном коде, а не в этом фрагменте: скажем, если первоначальный вызов к серверу слишком длинный и вызывает таймаут или тупик.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...