C # Uma conexão existente foi forçosamente fechada pelo host remoto: programação de soquete

Eu estou trabalhando com sockets. Aqui estão meus códigos (a descrição do problema é mais):

Lado do cliente :

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

Eu recebo erro nesta linha: int bytesRead = handler.EndReceive(ar);

Como posso evitar esse erro ?: An existing connection was forcibly closed by the remote host

Lado do servidor :

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

Você está recebendo uma exceção do handler.EndReceive() . Embora admitimos que não esteja claro por que você está recebendo a exceção específica que você mencionou, quando colocado em produção, este código lançará exceções toda vez que houver um problema de comunicação de rede (o que é comum).

Portanto, você provavelmente deve colocar um try / catch em torno da chamada para EndReceive() qualquer maneira. Pense no que seu código precisaria fazer sempre que a conexão falha ou o servidor morre ou algo assim.

Então você pode começar a diagnosticar problemas específicos. Uma coisa importante que você não especificou: você recebe esse erro apenas ocasionalmente ou você o recebe repetidamente o tempo todo ? Se é o primeiro, então pode ser apenas flutuações de conectividade de Internet normais. Seu software terá que ser capaz de lidar com isso. Se é o último, então eu acho que isso soa como um problema no servidor. Quando você chama BeginReceive() , seu sistema vai começar a esperar por algo do servidor; se esse “algo” é que ele recebeu dados, EndReceive() terá êxito, mas se esse “algo” for que o servidor fechou a conexão , seu retorno de chamada ainda será invocado e, em seguida, EndReceive() lançará o SocketException relevante . Isso ocorre por design, porque não há praticamente nenhuma outra maneira de se comunicar com o código que o servidor fechou a conexão.

EDIT: Parece que seu código de servidor precisa do mesmo tratamento de erros: sua chamada para EndReceive() é igualmente propensa a lançar uma exceção se o cliente fecha a conexão. (Eu sei que você tem um try / catch em torno de toda a grande coisa, mas gera um MessageBox … que não vai funcionar bem em um servidor, a menos que você queira alguém sentado lá o tempo todo clicando em todos os botões OK. ..)

Com base no seu erro, não tenho certeza se o problema está no código, pode estar no servidor. Além de adicionar alguma verificação de estado para validar que handler.EndReceive(ar) retornará algo útil, você provavelmente precisará verificar o próprio servidor (ou pedir às pessoas que o mantêm) para ver por que ele está fechando a conexão em você .

No final, o código do problema pode estar em seu código inicial, em vez de nesta parte: digamos, se a chamada inicial para o servidor for muito longa e causar um tempo limite ou um impasse.