2010-08-02 111 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 2010-08-02 15:54:46

+0

你是唯一訪問服務器的客戶端嗎?難道服務器已超出允許的連接數?如果你有權訪問服務器代碼,你知道它是否被調用嗎? – 2010-08-02 15:57:53

+0

還有其他可以訪問服務器的客戶端。 – 2010-08-02 16:04:41

回答

3

您從handler.EndReceive()獲得例外。雖然目前還不清楚爲什麼您收到您提到的特定異常,投入生產時,此代碼將在每次出現網絡通信問題(這很常見)時拋出異常。

因此,您應該嘗試圍繞EndReceive()撥打電話。想想你的代碼在連接失敗或服務器死亡或其他情況時需要做什麼。

然後您可以開始診斷特定問題。你還沒有具體說明一件重要的事情:你是否偶爾得到這個錯誤或者你是否可以一直得到它?如果是前者,那麼它可能只是普通的互聯網連接波動。你的軟件必須能夠處理這些。如果是後者,那麼我認爲這聽起來像是服務器上的問題。當您撥打BeginReceive()時,您的系統將開始等待服務器上的某些內容;如果那個「東西」是它接收到的數據,那麼EndReceive()會成功,但如果這個「某事」是服務器已經關閉連接,你的回調仍然會被調用,然後EndReceive()會拋出相關的SocketException。這是設計的,因爲幾乎沒有其他方法可以與代碼通信,即服務器已關閉連接。

編輯:看起來像你的服務器代碼需要同樣的錯誤處理:其EndReceive()通話同樣容易發生如果客戶關閉連接拋出異常。 (我知道你有一個嘗試/抓住周圍的大事情,但它輸出一個MessageBox ...這是不會在服務器上運行良好,除非你想要有人坐在那裏所有的時間點擊所有的確定按鈕...)

+0

我幾乎每次都收到錯誤 – 2010-08-02 16:39:10

+0

因此?我已經回答了。 – Timwi 2010-08-02 16:45:17

0

根據您的錯誤,我不確定問題出在您的代碼上,它可能在服務器上。除了添加一些狀態檢查來驗證handler.EndReceive(ar)將返回一些有用的信息之外,您可能需要檢查服務器本身(或者要求維護它的人員這樣做)查看爲什麼它會關閉您的連接。

最後,問題代碼可能在您的初始代碼中,而不是在這一塊:例如,如果對服務器的初始調用過長並導致超時或死鎖。

+0

我發佈服務器端代碼too.kindly幫助我。 – 2010-08-02 16:08:35

相關問題