2015-01-16 7 views
1

C#에서 스레드를 사용하여 서버에서 http 게시 요청을하는 것을 목표로하는 APPLICATION이 있습니다. (실제로는 다른 URI에서 요청을하는 여러 가지 다른 머리글이 있기 때문에 문제를 간단하게 처리 할 수 ​​있습니다.)내 서버에서 게시물을 만드는 C#의 스레드 - 홍수

다른 트레드는 다른 기간에 요청하도록 설정되어있는 것으로 나타났습니다. 그러나 나는 서버에서 홍수를 감지하고 있습니다. 항상 똑같은 ips와 거대한 연속열에서 오는 것이지요. - DDoS 공격과 같습니다! 실제로, 제 서버는 심각한 문제를 가지고 있습니다.

개인적으로 공격이라고 생각하지 않지만, 수천 명의 고객에게 배포되는 C# 응용 프로그램에 문제가있을 수 있습니다. 약 10,000. 그러면 하루에 최대 10K 건의 요청을 받게됩니다. 하지만 실제로는 더 많은 것이 있습니다 ...

제 서버는 파이썬입니다.

그리고 아래에서는 이러한 요청을하는 트레드에 코드 예제를 붙여 넣습니다. 나는이 모든 것을 설명하고 누군가가 볼 수 없다는 것을 알 수있는 희망의 코드를 보여줍니다. 잘못된 것을 발견 할 수 있으면, 귀하의 도움을 크게 주시면 감사하겠습니다.

DateTime nextCheck= DateTime.Now; 
void checkLicenses() 
{ 
    // 5 minutes 
    autoResetEvent.WaitOne(300000, true); 
    while (this.ServiceAlive) 
    { 

     if (DateTime.Now < nextCheck) 
     { 
      autoResetEvent.WaitOne(30000, true); 
      continue; 
     } 

     if (this.InternetIsOk) 
     { 
      Monitor.Record("Executing checkLicenses...", Mode.Console, false); 

      licenseRequest = new LicenseRequest() 
      { 
       token = this.GetToken(), 
       licensesList = Data.GetLicensesToValidate() 
      }; 

      string json = JsonConvert.SerializeObject(licenseRequest, Formatting.Indented); 
      var jsonBytes = Encoding.Default.GetBytes(json); 


      string URI = AplicationConf.GetWebServiceAddress() + "/checklicense"; 
      var uri = new Uri(URI); 
      var servicePoint = ServicePointManager.FindServicePoint(uri); 
      servicePoint.Expect100Continue = false; 
      System.Net.ServicePointManager.Expect100Continue = false; 

      string response = ""; 
      using (WebDownload wc = new WebDownload()) 
      { 
       wc.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded"; 
       wc.Credentials = CredentialCache.DefaultCredentials; 
       wc.Proxy = GetProxyData(); 
       wc.Timeout = 60000; 

       Monitor.Record("Post in URI: " + URI, Mode.Console, false); 
       var postResponse = wc.UploadData(URI, "POST", jsonBytes); 
       response = Encoding.Default.GetString(postResponse); 
      } 

      if (!String.IsNullOrEmpty(response)) 
      { 
       List<ResponseLicense> responseLicense = JsonConvert.DeserializeObject<List<ResponseLicense>>(response); 
       Data.UpdateLicense(responseLicense); 
      } 

      Monitor.Record("CheckLicense finish"); 
     } 
     nextCheck = DateTime.Now.AddHours(24); 
    } 
} 

UPDATE

이 응용 프로그램은 HostServer라는 클래스를 포함하는 WCF 서비스입니다. 이 클래스에는 서비스 시작시 한 번만 호출되는 Start() 메서드가 있습니다. 이 방법 "시작"은 머리를 만듭니다. checkLicenses() 메소드는 trhead입니다. 아래는 Start() 코드의 일부입니다.

public void Start (bool consoleRunning = false) 
{ 

   // code above 

   trheadCheckLicense = new Thread (new ThreadStart (checkLicense)); 
    trheadCheckLicense.Priority = ThreadPriority.Normal; 
   trheadCheckLicense.Name = "trheadCheckLicense"; 
   trheadCheckLicense.Start(); 

  // More code below 

}

+1

스레드를 지연 시키려면 ['Thread.Sleep'] (http://msdn.microsoft.com/en-us/library/system.threading.thread.sleep)을 사용하십시오. 사건을 학대하다. 고정 지연 ('Thread.Sleep (targetTime - DateTime.Now)')으로 루핑하기보다는 기다릴 총 시간을 계산하십시오. (비동기로 일을 처리하고 스레드를 전혀 차단하지 않는 것이 더 좋다.) – Richard

+0

checkLicenses() 메소드를 호출하는 코드와이를 포함하는 클래스에 대해 더 자세히 설명해 주시겠습니까? 앱에서 라이센스를 확인하는 여러 객체를 만들 수 있습니까? – gabba

+1

@gabba, 위의 코드는 사용자가 요청한 내용을 반영하도록 업데이트되었습니다. 감사. – ECC

답변

2

귀하의 CheckLicense 코드는 예외를 잡을 did't. 서비스를 다시 시작하도록 구성한 경우 실패합니다. 그리고 당신의 autoResetEvent는 새로운 AutoResetEvent처럼 생성됩니다 (true); 루프를 얻습니다 :

1 service starting 
2 go to check license 
3 send request 
4 get exception somewhere 
5 crash 
6 restart again 
+0

팁 주셔서 감사합니다, gabba! 어쨌든, 나는 cacth를 사용하여 메소드를 보호했으며 다중 서비스 객체를 잘못 작성했는지 확인하기 위해 서비스를 검토 중이며 충돌이 발생했는지 테스트하기 위해 루프에서 서비스를 호출합니다. – ECC

+0

또한 @ECC는 신호 상태로 만든 경우 AutoResetEvent를 작성한 방법을 확인하는 것을 잊지 않습니다. – gabba