社区
Delphi
帖子详情
在多线程调用 端口扫描中,如何处理 N个IP+N个Port的情况?我的笨方法是一个ip+端口 启动一个线程但总不能一次启动1千以上个线程运转的
cclq
2005-03-11 05:20:41
在多线程调用 端口扫描中,如何处理 N个IP+N个Port的情况?我的笨方法是一个ip+端口 启动一个线程但总不能一次启动1千以上个线程运转的吧?
如何处理?
用线程池,或者别的算法?
...全文
401
27
打赏
收藏
在多线程调用 端口扫描中,如何处理 N个IP+N个Port的情况?我的笨方法是一个ip+端口 启动一个线程但总不能一次启动1千以上个线程运转的
在多线程调用 端口扫描中,如何处理 N个IP+N个Port的情况?我的笨方法是一个ip+端口 启动一个线程但总不能一次启动1千以上个线程运转的吧? 如何处理? 用线程池,或者别的算法?
复制链接
扫一扫
分享
举报
写回复
配置赞助广告
用AI写文章
27 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
cclq
2005-03-28
打赏
举报
回复
我的想法好像不错,但是代码写起来复杂多了。思考中...
cclq
2005-03-28
打赏
举报
回复
间隔时间 是同一个IP+Port的每次扫描之间的 ,就比如:192.168.2.2:80 扫描 100次,每次扫描间隔为1秒,
梦想家大魔王
2005-03-28
打赏
举报
回复
要看你设置的那个间隔时间是每个IP+Port之间的还是同一个IP+Port的每次扫描之间的,我是把它理解成每个IP+Port之间的间隔了。你的想法不错,我前面大概也就是这个意思。有一点要注意,只有在多CPU的机器上使用多线程才能真正获得性能上的提升,而且创建、切换和销毁线程也是要消耗CPU时间的,要控制这个时间不要让它占太大的比例,在一个线程内循环执行多次要比在多个线程内各执行一次的效率高。
cclq
2005-03-28
打赏
举报
回复
根据 skyhero(天骄) 的提示,我现在整理一下自己的看法
管理类初始化200个工作线程(最好可以更改)
管理类接收命令信息,解析到一个公用的命令列表中(ClientDataSet)
这200个工作线程轮流执行这个命令列表中的扫描信息,比如有300个需要扫描的ip+Port,那么
这200个工作线程就执行那200个IP+Port一次,大概是200个工作线程执行一次后,其中的100个会重新再执行另外的100个ip+Port。
单个工作线程每执行1个ip+port后,进行同步扫描结果(扫描结果也是一个公用的ClientDataSet),同时该ip+port的扫描次数减少一(若是无限扫描次数另外考虑)
cclq
2005-03-28
打赏
举报
回复
我想是不是可以这樣:管理類啓動200個工作綫程等待StringList命令(相當于綫程池,StringList信息我解析后放到一個全局的ClientDataSet中),通過一種協作的方式輪流工作,這200個工作綫程 輪流全面 掃描完成一次后,再根據每個命令掃描次數信息判定是否中斷(去掉)這個掃描命令,每全面掃描一次,StringList的命令信息中的掃描次數就減少1,直到為0
這樣可行嗎?
代碼實現上能否給點提示?
很謝謝 skyhero(天骄)的無私參與 ,若不介意,我另開帖子共給你200分。
cclq
2005-03-24
打赏
举报
回复
领会中.....
请稍后.....
梦想家大魔王
2005-03-24
打赏
举报
回复
当扫描结束后要记得释放内存:
var
i: Integer;
AScanNode: TScanNode;
begin
with TheList.LockList do
try
for i := 0 to Count - 1 do
begin
AScanNode := TScanNode(Items[i]);
if AScanNode <> nil then AScanNode.Free;
end;
Clear;
finally
TheList.UnlockList;
end;
end;
梦想家大魔王
2005-03-24
打赏
举报
回复
管理类只负责接收参数、创建工作线程和统计最后的扫描结果,不需要为每个工作线程硬性指派工作。
保存IP和Port的列表可以由管理类和工作线程类共享,工作线程启动后可以自己从里面读取要扫描的IP和Port。用于保存扫描信息的数据结构,我觉得用一个自定义记录体或者类会更方便一些:
...
type
TScanNode = class(TObject)
strIP: string;
iPort: Integer;
iLoopCount: Integer;
iDelay: Integer;
end;
而且因为涉及到多线程同步问题,列表最好使用线程安全的TThreadList,当然在这里因为工作线程只从列表里读数据而不向列表里面写数据,使TList的话也不会有什么问题。
...
var
TheList: TThreadList; {全局变量}
...
{管理类接收外部参数以后}
var
AScanNode: TScanNode;
begin
AScanNode := TScanNode.Create;
with AScanNode do
begin
strIP := 传入的IP;
iPort := 传入的Port;
iLoopCount := 传入的扫描次数;
iDelay := 传入的间隔时间值;
end;
with TheList.LockList do
try
Add(AScanNode);
finally
TheList.UnlockList;
end;
...
end;
cclq
2005-03-24
打赏
举报
回复
skyhero(天骄) :
你好,按照你的意思我下面的命令信息应该在管理类中处理并分配到各个线程内(1个ip+N个端口)
管理類 負責接收一個StringList類型的命令信息(一次性接收可能5千个),格式如下:
'192.168.1.1 ; 21 ; 100 ; 1000' // StringList[0]
'192.168.1.1 ; 8080 ; 100 ; 1000' // StringList[1]
'192.168.1.1 ; 80 ; 100 ; 1000' // StringList[2]
'192.168.2.2 ; 8080 ; 100 ; 1000' // StringList[3]
'192.168.2.2 ; 808 ; 100 ; 1000' // StringList[4]
'192.168.2.5 ; 808 ; 100 ; 1000' // StringList[5]
.........
梦想家大魔王
2005-03-24
打赏
举报
回复
一个IP加一个端口号组成了列表中的一条记录,也就是一个完整的被扫描单位。设置一个全局整型变量P,工作线程每次都是取得StringList[P]处的这条记录,然后马上使P的值加一,这样另一个线程读取数据的时候得到的就是下一条记录了。
如果把IP、端口、扫描次数、间隔时间等信息都放进一个string里,那么你应该有自己的组合这些信息以及提取这些信息的自定义函数,具体怎么做要看你自己是怎么定义的。我感觉还是用记录体或者类来保存这些信息比较方便,不用费心思去处理这些字符串。
cclq
2005-03-24
打赏
举报
回复
还是有个问题不明白,下面的这些信息列表,如何甄别一个ip只启动一个线程?而且众多端口信息怎么获得?
工作线程取得StringList[0],[1],[2]
'192.168.1.1 ; 21 ; 100 ; 1000' // StringList[0]
'192.168.1.1 ; 8080 ; 100 ; 1000' // StringList[1]
'192.168.1.1 ; 80 ; 100 ; 1000' // StringList[2]
'192.168.2.2 ; 8080 ; 100 ; 1000' // StringList[3]
'192.168.2.2 ; 808 ; 100 ; 1000' // StringList[4]
'192.168.2.5 ; 808 ; 100 ; 1000' // StringList[5]
梦想家大魔王
2005-03-23
打赏
举报
回复
如果Port不是连续的,那么可以放在一个数组里。如果是连续的,你只需要保存这个连续范围的最大值和最小值。或者是分段连续的,你可以把需要跳过的端口号保存起来。甚至不需要接受传入的Port,因为一共就那么多个端口,从头遍历也不是不可行。
不必硬性规定每个线程负责扫描那些IP,只要线程完成一个IP的扫描后发现还有没扫描过的IP,那么就取得这个IP开始扫描。当然取得这个IP之后要立即把它标记为已扫描,避免其它工作线程重复扫描这个IP。
cclq
2005-03-23
打赏
举报
回复
skyhero(天骄):
谢谢。
IP保存在一个TStrings里面,那么,对应IP的N个端口放到哪儿?
一次创建N个线程,每个线程开始运行时都从IP列表中取得当前未开始扫描的第一个IP
///如何分配N个线程的IP?
梦想家大魔王
2005-03-23
打赏
举报
回复
极端的情况是创建一个工作线程只扫描一个IP+Port的组合,但一般情况就是一个工作线程要负责若干个IP+Port的组合的扫描。就像蚂蚁搬家,要搬的东西很多,但蚂蚁数量有限,只好一趟一趟搬,搬完为止。
梦想家大魔王
2005-03-23
打赏
举报
回复
一次性创建大量的工作线程不是一个好主意,可能不仅不会获得性能上的提高,搞不好还有反效果。创建出上千个工作线程,估计只有一些大型的服务器程序需要那么做。
你的意思是不同的IP需要扫描的端口可能不一样吧?按照你提供的格式,你可以在管理类中设置一个属性MaxThreadCount: Integer;用来控制一次性创建的工作线程的最大数量。
如果传入的IP+Port的组合数据条目数量小于等于MaxThreadCount,那么就创建同样多的工作线程一对一地扫描,每个线程只工作一次;如果传入的数据条目数量超过了MaxThreadCount(这应该是一般情况),那么就创建MaxThreadCount个工作线程,每个线程都要循环工作直到所有工作都做完。
...
var
IPAndPortList: TStringList;
MaxThreadCount, {工作线程最大数目}
CurrentListID: Integer; {列表中第一条未扫描数据的序号}
...
{工作线程的执行部分}
procedure TScanThread.Excute;
var
IP: string; {当前要扫描的IP}
i,
Port, {当前要扫描的端口}
LoopCount: Integer; {扫描次数}
begin
while (not Terminated)
and (CurrentListID < IPAndPortList.Count) do
begin
{TODO: 从列表中读取一条数据,并且使CurrentListID的值加1,注意同步}
...
{TODO: 从读取的数据中取得IP, Port, LoopCount的值}
...
{开始对当前的IP+Port扫描}
for i := 0 to LoopCount - 1 do
begin
{TODO: 扫描}
...
{TODO: 保存或者输出扫描结果}
...
end;
...
Sleep(间隔时间);
end;
end;
cclq
2005-03-23
打赏
举报
回复
我正在寫一個可重用的掃描單元,單元内定義了一個掃描管理類和一個掃描綫程類
管理類 負責接收一個StringList類型的命令信息,格式如下:
'192.168.1.1 ; 21 ; 100 ; 1000' // StringList[0]
'192.168.1.1 ; 8080 ; 100 ; 1000' // StringList[1]
'192.168.2.2 ; 8080 ; 100 ; 1000' // StringList[2]
.....
ip port 扫描次数 间隔
管理類接受后,集中創建綫程實例執行。(我現在的做法是每一個Ip+Por創建一個綫程)集中創建綫程的時候把其指針記錄到一個StringList中,然後集中執行縣程。
問題是,若管理類接受的StringList.Count 數目很大的時候,内存就會不夠(大約1000個綫程佔用45M内存)
這樣做法行嗎?
能否給點解決此類問題的提示?
謝謝!
cclq
2005-03-23
打赏
举报
回复
skyhero(天骄) :
是这样的,怪我的问题还是没有说清楚:我正在写一个可重用的扫描单元,定义了一个管理类和一个
线程类。管理类负责接收扫描IP+port信息,是Stringlist的格式的如:
'192.168.1.1 ; 21 ; 100 ; 1000'
ip port 扫描次数 间隔
管理类接收N个扫描信息后,解析,然后Create 线程执行。(产生N个线程,记录其指针到管理类的Stringlist中,然后再执行)
现在的问题就是,总不能一个ip+port就create一个线程吧?
有没有什么好一点的解决办法?效率高点的,如线程池技术。
若一个ip +N个端口 用一个线程来扫描,那么线程类的写法就复杂些了,很想听听你的意见。
cclq
2005-03-23
打赏
举报
回复
skyhero(天骄) :
是这样的,怪我的问题还是没有说清楚:我正在写一个可重用的扫描单元,定义了一个管理类和一个
线程类。管理类负责接收扫描IP+port信息,是Stringlist的格式的如:
'192.168.1.1 ; 21 ; 100 ; 1000'
ip port 扫描次数 间隔
管理类接收扫描信息后,解析,然后Create 线程执行。
现在的问题就是,总不能一个ip+port就create一个线程吧?
有没有什么好一点的解决办法?
cclq
2005-03-22
打赏
举报
回复
就讨论成这样?
梦想家大魔王
2005-03-22
打赏
举报
回复
假设所有IP保存在一个TStrings里面,设置一个全局变量P: Integer,P是列表中当前还没有开始扫描的第一个IP的序号。
一次创建N个线程,每个线程开始运行时都从IP列表中取得当前未开始扫描的第一个IP,并且修改P的值让它指向下一个IP。线程内部扫描这个IP的所有Port。
扫描完一个IP的所有Port,如果还有未开始扫描的IP,就再取得一个开始扫描。如果发现所有IP都被扫描过了,则结束当前线程。
所有工作线程结束后,输出扫描结果。
加载更多回复(7)
Python
多
线程
端口
扫描
与Socket通信实战:从原理到安全工具开发
网络编程是计算机通信的基础,其核心在于通过套接字(Socket)实现不同主机间的数据交换。Socket作为操作系统提供的抽象接口,封装了TCP/
IP
协议栈的底层细节,允许开发者以流或数据报的形式进行网络通信。理解Socket的工作原理,特别是TCP三次握手和连接状态管理,是构建稳定网络应用的基石。在安全工程和自动化运维领域,
端口
扫描
作为网络探测的基础技术,通过尝试与目标主机的特定
端口
建立连接,来发现开放的服务和潜在的攻击面。传统单
线程
扫描效率低下,而
多
线程
技术通过并发执行I/O操作,能极大提升扫描速度,这正
Python实战:从零构建
多
线程
端口
扫描
器,深入理解网络编程与安全测试
端口
扫描
是网络安全和信息收集领域的基础技术,其核心原理基于TCP/
IP
协议栈的通信机制。通过分析TCP三次握手过程
中
的SYN、SYN-ACK、RST等数据包响应,可以判断目标主机
端口
的开放、关闭或被过滤状态。掌握
端口
扫描
技术对于系统管理员进行服务暴露自查、安全工程师实施授权渗透测试具有重要价值,是构建主动防御能力和理解网络边界安全的关键实践。本文聚焦于使用Python的socket库实现底层网络通信,并结合threading与concurrent.futures模块构建高效的
多
线程
并发扫描引擎,通过实战项目
渗透测试必备:御剑
端口
扫描
工具的核心原理与实战技巧
端口
扫描
是网络安全信息收集的基础技术,其核心原理是通过TCP/
IP
协议与目标主机
端口
建立连接,以探测服务开放状态。传统串行扫描效率低下,而
多
线程
并发技术通过同时发起大量连接请求,实现了扫描速度的指数级提升,这正是御剑等高效扫描工具的技术基石。在工程实践
中
,这种高速扫描能力对于大型网络资产发现、安全评估和渗透测试前期情报收集具有重要价值,能帮助安全工程师快速勾勒网络拓扑,定位潜在攻击面。本文将结合
多
线程
并发和TCP连接扫描等关键技术,深入解析御剑工具在实战
中
的应用场景与优化策略。
Python实战:从零构建红队渗透测试的轻量级
端口
扫描
与漏洞探测脚本
端口
扫描
与漏洞探测是网络安全评估和信息收集的核心环节,其原理基于网络协议(如TCP/
IP
)的交互。通过发送特定的数据包并分析响应,可以识别目标主机开放的
端口
、运行的服务及其潜在风险。这项技术的价值在于能够自动化、高效地梳理资产暴露面,为安全加固和渗透测试提供关键入口。在红队演练、内网资产梳理等应用场景
中
,
一个
高度定制化、易于集成的轻量级工具尤为重要。本文聚焦于使用Python实现
一个
轻量级
端口
扫描
器与漏洞探测脚本,深入探讨了TCP SYN扫描、服务指纹识别等关键技术,并分享了在性能优化和隐蔽性增强方面的工程
基于Qt/C++实现跨平台局域网
IP
端口
扫描
器:从原理到工程实践
网络探测是网络管理与安全领域的基础技术,其核心原理在于通过特定的协议与目标主机建立连接或发送探测包,以判断其在线状态及服务可用性。在工程实践
中
,TCP连接扫描是最常用且易于实现的技术之一,它模拟标准的三次握手过程,通过分析连接响应(如SYN-ACK或RST)来判断
端口
状态。这项技术的价值在于能够快速盘点网络资产、进行服务发现及安全评估,广泛应用于内网运维、软件集成与安全测试等场景。本文聚焦于利用Qt框架的跨平台网络库,如QTcpSocket和QNetworkInterface,构建
一个
轻量级、无外部依赖的异
Delphi
5,944
社区成员
262,941
社区内容
发帖
与我相关
我的任务
Delphi
Delphi 开发及应用
复制链接
扫一扫
分享
社区描述
Delphi 开发及应用
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章