1. Пользуйтесь тегами кода. - [code] ... [/code] 2. Точно указывайте язык, название и версию компилятора (интерпретатора). 3. Название темы должно быть информативным.
В описании темы указываем язык!!!
const int threadCount = 4; // Количество потоков int toProcess = threadCount; ManualResetEvent resetEvent;
public void DoIt(int start, int finish, string ip) // Функция потока { TcpClient TcpScan = new TcpClient(); for (int CurrPort = start; CurrPort <= finish; CurrPort++) { string s = ""; try { TcpScan.Connect(ip, CurrPort); s = "Port " + CurrPort + " open\r\n"; } catch { s = "Port " + CurrPort + " closed\r\n"; }
MethodInvoker action = delegate { txtLog.AppendText(s); }; // Синхронизация доп. потока с UI txtLog.BeginInvoke(action); } if (Interlocked.Decrement(ref toProcess) == 0) // Закончился последний из toProcess потоков? resetEvent.Set(); // Выставить событие, это будет поймано в WaitOne() }
// Это еще один доп. поток, контролирующий те, которые проверяют порты... // Если это сделать в обработчике OnClick кнопки, то WaitOne() будет блокировать UI-поток // до тех пор, пока все остальные потоки не завершатся, и потом просто все результаты // будут "выплюнуты" в textLog. Это не очень красиво, лучше сделать доп. поток, // пускай он блокируется вызовом WaitOne(), а UI будет работать без задержек... void MyControlThread() { string myHost = System.Net.Dns.GetHostName(); string myIP = System.Net.Dns.GetHostByName(myHost).AddressList[0].ToString(); int StartPort = Convert.ToInt32(numStart.Text); int EndPort = Convert.ToInt32(numEnd.Text);
int portCount = (EndPort - StartPort + 1) / threadCount; resetEvent = new ManualResetEvent(false); Thread[] th = new Thread[threadCount];
for(int i = 0; i < threadCount; i++) // Запускаем столько потоков, сколько нужно { int s = StartPort + i * portCount; // и каждому задаем начальный/конечный порт для сканирования int f = StartPort + (i + 1) * portCount - 1; th[i] = new Thread(() => DoIt(s, f, myIP)); //Собственно, создание потока th[i].Start(); // и его запуск } resetEvent.WaitOne(); // теперь ждем, пока всё завершится... MessageBox.Show("Сканирование завершено"); }
void Button1Click(object sender, EventArgs e) { // Ну, а тут - просто запускаем контролирующий поток... Thread thrd = new Thread(MyControlThread); thrd.Start(); }
Все просто... Но желательно, чтобы общее количество сканируемых портов было кратно числу потоков. Скажем, я проверял порты 200 - 263 (64 штуки), на 4-х потоках и на 8-ми...
Только не ожидай, что вывод результатов будет таким же, как и в твоем примере. Потому что тут порты проверяются совсем в другой последовательности...