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;//開(kāi)放端口號(hào)數(shù)量
public Form1()
{
InitializeComponent();
//CheckForIllegalCrossThreadCalls設(shè)置為false;然后就能安全的訪問(wèn)窗體控件
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("開(kāi)始掃描.......");
}
else
messages.Items.Add("繼續(xù)掃描......");
//開(kāi)始掃描禁用,停止掃描啟用
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++)
{
//按下停止掃描后開(kā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è)端口開(kāi)放");
}
beginScanning.Enabled = true;
stopScanning.Enabled = false;
//判斷是否掃描完畢
if (int.Parse(endPortText.Text) == port)
{
port = 0;
beginScanning.Text = "開(kāi)始掃描";
}
}
public void Scanning()
{
this.ports[port] = true;
try
{
TcpClient tmp = new TcpClient(ipAddressText.Text, port);
messages.Items.Add("端口" + port + "開(kāi)放");
count++;
}
catch (System.Exception ex)
{
}
}
private void stopScanning_Click(object sender, EventArgs e)
{
//按下停止按鈕后,開(kāi)始按鈕和停止按鈕狀態(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)三次握手,即該端口是開(kāi)放的。而其他端口(紅色)則是無(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;//開(kāi)放端口號(hào)數(shù)量
public Form1()
{
InitializeComponent();
//CheckForIllegalCrossThreadCalls設(shè)置為false;然后就能安全的訪問(wèn)窗體控件
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("開(kāi)始掃描.......");
}
else
messages.Items.Add("繼續(xù)掃描......");
//開(kāi)始掃描禁用,停止掃描啟用
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++)
{
//按下停止掃描后開(kā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è)端口開(kāi)放");
}
beginScanning.Enabled = true;
stopScanning.Enabled = false;
//判斷是否掃描完畢
if (int.Parse(endPortText.Text) == port)
{
port = 0;
beginScanning.Text = "開(kāi)始掃描";
}
}
public void Scanning()
{
this.ports[port] = true;
try
{
TcpClient tmp = new TcpClient(ipAddressText.Text, port);
messages.Items.Add("端口" + port + "開(kāi)放");
count++;
}
catch (System.Exception ex)
{
}
}
private void stopScanning_Click(object sender, EventArgs e)
{
//按下停止按鈕后,開(kāi)始按鈕和停止按鈕狀態(tài)翻轉(zhuǎn)
beginScanning.Enabled = true;
stopScanning.Enabled = false;
}
}
}
2.界面

3.結(jié)果
不會(huì)出現(xiàn)單線程的卡死,掃描速度也大大提升。同時(shí)可以隨時(shí)開(kāi)始和暫停操作。

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#重寫TabControl控件實(shí)現(xiàn)關(guān)閉按鈕的方法
這是關(guān)于c#重寫TabControl控件實(shí)現(xiàn)關(guān)閉按鈕的例子,整理了一下,與大家分享。2013-04-04
深入淺出掌握Unity ShaderLab語(yǔ)法基礎(chǔ)
Unity中所有Shader文件都通過(guò)一種陳述性語(yǔ)言進(jìn)行描述,稱為“ShaderLab”, 這篇文章主要介紹了Unity圖形學(xué)之ShaderLab入門基礎(chǔ),需要的朋友可以參考下2023-05-05
將數(shù)組中指定數(shù)量的元素移動(dòng)數(shù)組后面的實(shí)現(xiàn)代碼
本篇文章是對(duì)將數(shù)組中指定數(shù)量的元素移動(dòng)數(shù)組后面的實(shí)現(xiàn)代碼進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-06-06
基于Kubernetes實(shí)現(xiàn)前后端應(yīng)用的金絲雀發(fā)布(兩種方案)
這篇文章主要介紹了基于Kubernetes實(shí)現(xiàn)前后端應(yīng)用的金絲雀發(fā)布,文中給大家提到了兩種常用方案,通過(guò)示例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2021-12-12
C#結(jié)合OpenCVSharp4使用直方圖算法實(shí)現(xiàn)圖片相似度比較
這篇文章主要為大家詳細(xì)介紹了C#如何結(jié)合OpenCVSharp4使用直方圖算法實(shí)現(xiàn)圖片相似度比較,文中的示例代碼簡(jiǎn)潔易懂,需要的小伙伴可以參考下2023-09-09
C#實(shí)現(xiàn)對(duì)Json字符串處理實(shí)例
這篇文章主要介紹了C#實(shí)現(xiàn)對(duì)Json字符串處理,通過(guò)一個(gè)json實(shí)例分析了C#進(jìn)行JSON操作的方法,需要的朋友可以參考下2014-09-09

