C#?基于TCP?實(shí)現(xiàn)掃描指定ip端口的方式示例
一、單線程掃描
1.代碼
using System; using System.Windows.Forms; using System.Net; using System.Net.Sockets; using System.Threading; namespace SingleThreadScanningPort { public partial class Form1 : Form { private bool[] ports = new bool[65536];//所有端口號(hào) private static int port=0;//當(dāng)前端口號(hào) private static int count = 0;//開放端口號(hào)數(shù)量 public Form1() { InitializeComponent(); //CheckForIllegalCrossThreadCalls設(shè)置為false;然后就能安全的訪問窗體控件 CheckForIllegalCrossThreadCalls = false; //初始化進(jìn)度顯示為空 label2.Text = ""; //停止掃描按鈕為不可用 stopScanning.Enabled = false; } private void beginScanning_Click(object sender, EventArgs e) { //檢查端口號(hào) if (int.Parse(beginPortText.Text) < 0 || int.Parse(beginPortText.Text) > int.Parse(endPortText.Text) || int.Parse(endPortText.Text) > 65565) { messages.Items.Add("端口錯(cuò)誤!"); return; } //新建線程執(zhí)行掃描端口函數(shù) Thread procss = new Thread(new ThreadStart(ScanningPort)); procss.Start(); //設(shè)置進(jìn)度條最大值最小值分別為結(jié)束端口和起始端口 progressBar1.Maximum = int.Parse(endPortText.Text) - int.Parse(beginPortText.Text); progressBar1.Minimum = 0; //判斷是否為繼續(xù)掃描 if (port == 0) { messages.Items.Clear(); messages.Items.Add("開始掃描......."); } else messages.Items.Add("繼續(xù)掃描......"); //開始掃描禁用,停止掃描啟用 beginScanning.Enabled = false; stopScanning.Enabled = true; } public void ScanningPort() { int start; int end = int.Parse(endPortText.Text); //判斷是否為繼續(xù)掃描,如果是則繼續(xù)掃描,否則重新掃描 if (port != 0) start = port; else start = int.Parse(beginPortText.Text); messages.Items.Add("起始端口" + start); messages.Items.Add("結(jié)束端口" + end); for (int i = start; i <= end; i++) { //按下停止掃描后開始掃描按鈕啟用,此時(shí)停止掃描 if (beginScanning.Enabled) break; port = i; //新建線程進(jìn)行掃描 Thread thread = new Thread(Scanning); thread.Start(); //主線程休眠10ms System.Threading.Thread.Sleep(10); //修改進(jìn)度條的值 progressBar1.Value = i- int.Parse(beginPortText.Text); //顯示端口號(hào)以及進(jìn)度 label2.Text = "正在掃描端口: " + i+" 進(jìn)度: "+Math.Round(( (i - int.Parse(beginPortText.Text)) *100.0 / progressBar1.Maximum),2)+"%"; progressBar1.PerformStep(); } if (port != 0) beginScanning.Text = "繼續(xù)掃描"; else { messages.Items.Add("端口掃描結(jié)束"); messages.Items.Add("共有 " + count + " 個(gè)端口開放"); } beginScanning.Enabled = true; stopScanning.Enabled = false; //判斷是否掃描完畢 if (int.Parse(endPortText.Text) == port) { port = 0; beginScanning.Text = "開始掃描"; } } public void Scanning() { this.ports[port] = true; try { TcpClient tmp = new TcpClient(ipAddressText.Text, port); messages.Items.Add("端口" + port + "開放"); count++; } catch (System.Exception ex) { } } private void stopScanning_Click(object sender, EventArgs e) { //按下停止按鈕后,開始按鈕和停止按鈕狀態(tài)翻轉(zhuǎn) beginScanning.Enabled = true; stopScanning.Enabled = false; } } }
2.界面
3.結(jié)果
由于是單線程執(zhí)行,在掃描端口的時(shí)候程序會(huì)直接卡死。所以只簡(jiǎn)單掃描幾個(gè)端口
4.抓包
由于是通過(guò)以太網(wǎng)發(fā)送的,建議先注銷哆點(diǎn)再進(jìn)行抓包,減少數(shù)據(jù)。
可以發(fā)現(xiàn)3900端口成功實(shí)現(xiàn)三次握手,即該端口是開放的。而其他端口(紅色)則是無(wú)法建立連接,意味著是關(guān)閉的。
二、多線程掃描
1.代碼
using System; using System.Windows.Forms; using System.Net; using System.Net.Sockets; using System.Threading; namespace SingleThreadScanningPort { public partial class Form1 : Form { private bool[] ports = new bool[65536];//所有端口號(hào) private static int port=0;//當(dāng)前端口號(hào) private static int count = 0;//開放端口號(hào)數(shù)量 public Form1() { InitializeComponent(); //CheckForIllegalCrossThreadCalls設(shè)置為false;然后就能安全的訪問窗體控件 CheckForIllegalCrossThreadCalls = false; //初始化進(jìn)度顯示為空 label2.Text = ""; //停止掃描按鈕為不可用 stopScanning.Enabled = false; } private void beginScanning_Click(object sender, EventArgs e) { //檢查端口號(hào) if (int.Parse(beginPortText.Text) < 0 || int.Parse(beginPortText.Text) > int.Parse(endPortText.Text) || int.Parse(endPortText.Text) > 65565) { messages.Items.Add("端口錯(cuò)誤!"); return; } //新建線程執(zhí)行掃描端口函數(shù) Thread procss = new Thread(new ThreadStart(ScanningPort)); procss.Start(); //設(shè)置進(jìn)度條最大值最小值分別為結(jié)束端口和起始端口 progressBar1.Maximum = int.Parse(endPortText.Text) - int.Parse(beginPortText.Text); progressBar1.Minimum = 0; //判斷是否為繼續(xù)掃描 if (port == 0) { messages.Items.Clear(); messages.Items.Add("開始掃描......."); } else messages.Items.Add("繼續(xù)掃描......"); //開始掃描禁用,停止掃描啟用 beginScanning.Enabled = false; stopScanning.Enabled = true; } public void ScanningPort() { int start; int end = int.Parse(endPortText.Text); //判斷是否為繼續(xù)掃描,如果是則繼續(xù)掃描,否則重新掃描 if (port != 0) start = port; else start = int.Parse(beginPortText.Text); messages.Items.Add("起始端口" + start); messages.Items.Add("結(jié)束端口" + end); for (int i = start; i <= end; i++) { //按下停止掃描后開始掃描按鈕啟用,此時(shí)停止掃描 if (beginScanning.Enabled) break; port = i; //新建線程進(jìn)行掃描 Thread thread = new Thread(Scanning); thread.Start(); //主線程休眠10ms System.Threading.Thread.Sleep(10); //修改進(jìn)度條的值 progressBar1.Value = i- int.Parse(beginPortText.Text); //顯示端口號(hào)以及進(jìn)度 label2.Text = "正在掃描端口: " + i+" 進(jìn)度: "+Math.Round(( (i - int.Parse(beginPortText.Text)) *100.0 / progressBar1.Maximum),2)+"%"; progressBar1.PerformStep(); } if (port != 0) beginScanning.Text = "繼續(xù)掃描"; else { messages.Items.Add("端口掃描結(jié)束"); messages.Items.Add("共有 " + count + " 個(gè)端口開放"); } beginScanning.Enabled = true; stopScanning.Enabled = false; //判斷是否掃描完畢 if (int.Parse(endPortText.Text) == port) { port = 0; beginScanning.Text = "開始掃描"; } } public void Scanning() { this.ports[port] = true; try { TcpClient tmp = new TcpClient(ipAddressText.Text, port); messages.Items.Add("端口" + port + "開放"); count++; } catch (System.Exception ex) { } } private void stopScanning_Click(object sender, EventArgs e) { //按下停止按鈕后,開始按鈕和停止按鈕狀態(tài)翻轉(zhuǎn) beginScanning.Enabled = true; stopScanning.Enabled = false; } } }
2.界面
3.結(jié)果
不會(huì)出現(xiàn)單線程的卡死,掃描速度也大大提升。同時(shí)可以隨時(shí)開始和暫停操作。
4.抓包
和單線程的抓包思路以及結(jié)果都是一樣的
三、總結(jié)
單線程操作的時(shí)候會(huì)出現(xiàn)界面直接卡死并且掃描速度很慢,
多線程操作掃描速度大大提升而且不會(huì)出現(xiàn)界面卡死。
四、源碼
1.github
https://github.com/TangtangSix/SingleThreadScanningPort
https://github.com/TangtangSix/MultithreadingScanningPort
2.gitee
https://gitee.com/tangtangsix/SingleThreadScanningPort
https://gitee.com/tangtangsix/MultithreadingScanningPort
到此這篇關(guān)于C# 基于TCP 實(shí)現(xiàn)掃描指定ip端口的方式示例的文章就介紹到這了,更多相關(guān)C# 掃描指定ip端口內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C# winform編程中響應(yīng)回車鍵的實(shí)現(xiàn)代碼
這篇文章主要介紹了C# winform編程中響應(yīng)回車鍵的實(shí)現(xiàn)代碼,既在窗口上響應(yīng)回車鍵事件的方法,需要的朋友可以參考下2014-08-08C#8.0默認(rèn)接口實(shí)現(xiàn)的詳細(xì)實(shí)例
Microsoft使用C#8.0發(fā)布了許多新功能,他們引入的主要功能之一是默認(rèn)接口方法。這篇文章主要給大家介紹了關(guān)于C#8.0默認(rèn)接口實(shí)現(xiàn)的相關(guān)資料,需要的朋友可以參考下2021-05-05深入多線程之:解析線程的交會(huì)(Thread Rendezvous)詳解
本篇文章是對(duì)線程的交會(huì)(Thread Rendezvous)進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05c# 數(shù)據(jù)類型占用的字節(jié)數(shù)介紹
本篇文章主要是對(duì)c#中數(shù)據(jù)類型占用的字節(jié)數(shù)進(jìn)行了詳細(xì)的介紹。需要的朋友可以過(guò)來(lái)參考下,希望對(duì)大家有所幫助2014-01-01