2010-08-02 3 views
0

Я работаю с сокетами. Вот мои коды (описание проблемы дополнительно):C# Существующее соединение было принудительно закрыто удаленным хостом: программирование сокетов

стороны клиента:

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

Ум ... не принудительно закрывает соединение на удаленном хосте? – dtb

+0

Вы единственный клиент, обращающийся к серверу?Может быть, сервер превысил количество разрешенных подключений? Если у вас есть доступ к серверному коду, знаете ли вы, будет ли он вызван? –

+0

есть другие клиенты, у которых есть доступ к серверу. –

ответ

3

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

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

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

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

+0

Я получаю ошибку почти каждый раз –

+0

Итак? Я уже ответил на это. – Timwi

0

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

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

+0

я тоже отправляю серверный код. –

Смежные вопросы

 Смежные вопросы