2017-12-30 51 views
0

저는 C#으로 간단한 포트 스캐너를 만들고 있습니다. 나는 이미 포트 스캐닝 기능을 가지고 있으며 사용자는 사용할 스레드 수와 IP 주소 범위를 전달한다. 따라서 현재 내가 범위를 파싱하고 해당 범위의 모든 IP 주소를 포함하는 ConcurrentBag을 만들었습니다. 스레드 배열도 있습니다.C#에서 쓰레드와 ConcurrentBag 사용하기

var ipsInRange = IPAddressRange.Parse(range); 

Thread[] hostThreads = new Thread[(int)threads]; 
ConcurrentBag<IPAddress> ips = new ConcurrentBag<IPAddress>(); 
foreach (var ip in ipsInRange) 
{ 
    ips.Add(ip); 
} 

IPAddress address; 
while (!ips.IsEmpty) 
{ 
    if (ips.TryTake(out address)) 
    { 
     PortScanner ps = new PortScanner(address); 
     ps.Scan(); 
    } 
} 

// I want to assign each thread one IP address, create a new PortScanner 
// instance as above, and scan the IP. I want to delete the scanned IPs 
// from the bag. When the thread finishes with scanning, I want to assign 
// a new one to it. I want to continue like this until the bag is empty, 
// i.e. all the IPs are processed. 
// So, simply I want to scan multiple IPs at the same time, using the above 
// thread array and the ConcurrentBag containing list of IPs. 

비록, 내가 전에 ThreadsConcurrentBag을 사용하지 않은, 그리고 제가 코멘트에 위의 기록 달성하고자 : 그래서, 그것은 부분적으로 다음과 같습니다. 모든 아이디어 어떻게 응용 프로그램에 위의 스레드를 통합 할 수 있습니까?

+0

자신을 교육하는 데 도움이되는 멀티 스레드 네트워크 프로그래밍에 대한 자료를 검색하십시오. –

답변

2

스레드를 직접 관리하는 대신 Task Parallel Library을 사용하는 것이 좋습니다. 짧고 읽기 쉬운 코드로 이어지고 스레드 나 ConcurrentBag를 다룰 필요가 없습니다.

모든 IP 주소 (예 : 당신은 포트 스캔하는 동안 IP 주소를 추가/제거 할 필요는 없습니다) 포트 스캔이 시작되기 전에 알려진 경우, 코드는 다음과 같이 간단 할 수 있습니다

var ipsInRange = IPAddressRange.Parse(range); 

var options = new ParallelOptions() 
{ 
    MaxDegreeOfParallelism = 5// Set number of IP addresses to be processed concurrently 
}; 

Parallel.ForEach(
    ipsInRange, 
    options, 
    (address) => { PortScanner ps = new PortScanner(address); ps.Scan(); }); 

당신이 필요로하는 경우 포트 스캔이 진행되는 동안 (다른 스레드로부터) IP 주소 목록을 수정할 수있는 시나리오를 지원하려면 ipsInRange 콜렉션을 BlockingCollection에 넣어야합니다. 그러나 질문에 따라 필요하지 않은 것으로 보입니다.

1

내가 솔루션을 보듯 :

  1. 는 coolection에서 IP를 소요하는 여러 작업을 만들기
  2. IP-주소 blocking collection을 만들고 검사합니다.

    var bc = new BlockingCollection<string>(); 
    //... 
    bc.Add(ip); //add addresses from another thread, or smth else 
    //... 
    
    for(int i = 0; i < 10; i++) 
    { 
        Task.Run(()=> 
        { 
         var address = bc.Take(); 
         PortScanner ps = new PortScanner(address); 
         ps.Scan(); 
        }); 
    } 
    

당신은 주소를 스캔 10 개 스레드를 가지고 컬렉션 그들에게 다음 요소를 제공 할 수있는 동안 그들은 기다립니다.

+0

답해 주셔서 감사합니다. 나는 이것을 시도했지만 분명히 효과가 없다. 내가 for 루프를 실행한다는 것을 알아 차렸지만'i' 만 증가시키고 나간다. 'Task.Run' 부분으로 들어가서 그 안의 모든 것을 건너 뜁니다. 어떤 아이디어가 빠졌습니까? – tinker

+0

@tinker 건너 뛰지 않습니다. 그것은 새로운 스레드를 시작하고'Run' 메서드 내에서 코드를 실행합니다. – Backs

+0

매우 빨리 끝나고 콘솔을 인쇄하지도 않습니다. 일반적으로 프로그램을 실행하면 콘솔에 내용이 인쇄됩니다. 둘째, 중단 점을 넣으면 '주소'에 말하면서 멈추지 않습니다. 이전에는 비슷한 코드를 사용하고 있었지만'List '을 사용한 다음 끝에 Task.WaitAll()을 실행했습니다. 작업을 마칠 때까지 약간의 시간이 걸렸습니다. – tinker