Python自制端口扫描器

发布时间 2023-05-09 11:31:44作者: 时人不识凌云木

自制Python端口扫描器

一、工具介绍

这个Python端口扫描器实现了一个基于 PyQt5 的端口扫描器界面,主要包含以下部分:

1. 使用 `setdefaulttimeout()` 方法设置默认的超时时间为 0.001 秒。
2. 使用 `socket` 模块创建一个套接字,并尝试与指定的端口进行连接。
3. 如果连接成功,则在文本浏览器中显示相应信息;否则,说明该端口没有开放。
4. 创建一个应用程序对象,一个对话框和一个 UI_Dialog 对象,并将其设置为对话框的 UI。
5. 显示对话框并进入事件循环。

其中,`setupUi()` 方法实现了界面的初始化和控件的创建和布局,`retranslateUi()` 方法实现了控件名称的翻译和信号槽的连接,

`portscanner()` 方法实现了具体的端口扫描功能,`start()` 和 `stop()` 方法实现了开始扫描和停止扫描的按钮响应,

`if __name__ == "__main__":` 语句判断该文件是否作为脚本直接运行。

二、设计思路

  1. 导入Python socket库,该库允许我们使用套接字以及客户端和服务器之间的连接;
  2. 定义要扫描的IP地址和端口范围;
  3. 创建一个循环来迭代要扫描的端口号;
  4. 对于每个端口,创建一个套接字并尝试连接到指定的主机和端口;
  5. 如果连接成功,则表示端口处于打开状态,可以将此信息输出到控制台或记录在文件中;
  6. 关闭套接字并继续循环,以便扫描所有指定的端口。

三、工具测试

1.打开命令行,ipconfig查看本机IP为10.0.188.182,输入IP到Dialog里,点击OK!

扫描结果展示在下方文本区内。

2.打开命令行,netstat -ano查看本机IP端口开放情况,发现和扫描结果一致。

由于目前该工具还没有引入线程,所以暂且测试0-6000端口,而不是总共的65536个端口。

但是我也修改了超时时间来提高速度,但是在网络质量不好的情况下会出现疏漏。

四、编程源代码

# 设置文件编码为 utf-8
# -*- coding: utf-8 -*-

from PyQt5 import QtCore,QtWidgets
import socket
import sys

class Ui_Dialog(object):
def setupUi(self, Dialog):
# 设置对话框的名称和大小
Dialog.setObjectName("Dialog")
Dialog.resize(400, 300)

# 创建一个单行文本编辑器,用于输入要扫描的 IP 地址
self.lineEdit_ip = QtWidgets.QLineEdit(Dialog)
self.lineEdit_ip.setGeometry(QtCore.QRect(40, 30, 151, 20))
self.lineEdit_ip.setObjectName("lineEdit_ip")

# 创建一个文本浏览器,用于显示扫描结果
self.tb_ip = QtWidgets.QTextBrowser(Dialog)
self.tb_ip.setGeometry(QtCore.QRect(30, 80, 351, 192))
self.tb_ip.setObjectName("tb_ip")

# 创建开始扫描和取消按钮,并设置它们的名称和位置
self.bt_ok = QtWidgets.QPushButton(Dialog)
self.bt_ok.setGeometry(QtCore.QRect(210, 30, 75, 23))
self.bt_ok.setObjectName("bt_ok")
self.bt_cancel = QtWidgets.QPushButton(Dialog)
self.bt_cancel.setGeometry(QtCore.QRect(300, 30, 75, 23))
self.bt_cancel.setObjectName("bt_cancel")

# 将控件名称翻译为指定语言
self.retranslateUi(Dialog)

# 连接信号和槽函数
QtCore.QMetaObject.connectSlotsByName(Dialog)

def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "私人端口扫描器"))
self.bt_ok.setText(_translate("Dialog", "OK"))
self.bt_ok.clicked.connect(self.start)
self.bt_cancel.setText(_translate("Dialog", "Cancel"))
self.bt_cancel.clicked.connect(self.stop)

def portscanner(self, host, port):
try:
# 创建一个套接字,设置地址类型为 IPv4,传输协议为 TCP
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 尝试与目标主机的指定端口进行连接
s.connect((host, port))
# 如果连接成功,则在文本浏览器中显示相应信息
self.tb_ip.append("这个端口开放喽: %d " % port)
# 关闭套接字
s.close()
except:
# 发生异常,说明该端口没有开放
pass

def start(self):
# 获取要扫描的 IP 地址
ip = self.lineEdit_ip.text()
# 设置超时时间为 0.001 秒
socket.setdefaulttimeout(0.001)
# 对 0~6000 端口进行扫描
for p in range(0, 6000):
self.portscanner(ip,p)
# 显示扫描结束信息
self.tb_ip.append("扫描结束啦------ByeBye")

def stop(self):
# 退出程序
sys.exit()

if __name__ == "__main__":
# 创建一个应用程序对象
app = QtWidgets.QApplication(sys.argv)
# 创建一个对话框
form = QtWidgets.QDialog()
# 创建 Ui_Dialog 对象,并将其设置为 form 的 UI
ui = Ui_Dialog()
ui.setupUi(form)
# 显示对话框
form.show()
# 运行应用程序,进入事件循环
sys.exit(app.exec_())