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

您将从handler.EndReceive()获得exception。 虽然不确定为什么你收到你提到的特定例外还不清楚,但是当投入生产时,这个代码每次出现网络通信问题时都会抛出exception(这很常见)。

因此,您应该在调用EndReceive()调用try / catch。 想想只要连接失败或服务器死亡或其他什么,您的代码需要做什么。

然后,您可以开始诊断特定问题。 你没有指定一件重要的事情:你是偶尔得到这个错误还是你可以重复得到它? 如果它是前者,那么它可能只是正常的互联网连接波动。 您的软件必须能够处理这些。 如果是后者,那么我认为这听起来像服务器上的问题。 当你调用BeginReceive() ,你的系统将开始等待来自服务器的东西; 如果那个“东西”是它收到的数据,那么EndReceive()会成功,但如果那个“东西”是服务器关闭了连接 ,你的回调仍然会被调用,然后EndReceive()会抛出相关的SocketException 。 这是设计原因,因为几乎没有其他方法可以与服务器关闭连接的代码进行通信。

编辑:看起来您的服务器代码需要相同的error handling:如果客户端关闭连接, EndReceive()调用同样容易抛出exception。 (我知道你有一个尝试/捕捉整个大事,但它输出一个MessageBox …在服务器上不能很好地工作,除非你希望有人坐在那里一直点击所有的OK按钮。 ..)

根据您的错误,我不确定您的代码是否存在问题,可能是在服务器上。 除了添加一些状态检查以validationhandler.EndReceive(ar)将返回一些有用的东西,你可能需要检查服务器本身(或询问维护它的人这样做),看看它为什么关闭你的连接。

最后,问题代码可能在您的初始代码中,而不是在此片段中:例如,如果对服务器的初始调用太长并导致超时或死锁。