Python 网络编程:端口检测与IP解析
在现代网络编程中,了解如何检查端口状态以及根据IP地址解析主机名是非常重要的技能。本文将介绍如何使用Python实现这两个功能,并提供相应的示例代码供读者参考。
一、检查端口是否打开
在网络应用中,判断一个特定端口是否开放可以帮助我们进行故障排查或安全审计。Python的socket
库为我们提供了方便的工具来完成这一任务。以下是一个简单的示例,实现了对指定主机和端口的检查:
# 定义一个扫描给定主机IP地址和端口函数,参数为目标主机、目标端口
def connScan(tgtHost, tgtPort):
try:
# 创建一个socket对象
connSkt = socket(AF_INET, SOCK_STREAM)
# 设置socket超时时间
connSkt.settimeout(1) # 设置为1秒
# 尝试连接到指定的主机和端口
result = connSkt.connect_ex((tgtHost, tgtPort))
# 如果返回值为0,说明端口开放
if result == 0:
print(f"端口 - {tgtPort} 在主机 {tgtHost} 上是开放的。")
else:
print(f"端口 - {tgtPort} 在主机 {tgtHost} 上是关闭的。")
except Exception as e:
print(f"发生异常:{e}")
finally:
connSkt.close()
代码解析
- 使用
socket()
创建一个TCP/IP socket。 settimeout()
方法用于设置连接的超时时间,以防止在连接过程中长时间阻塞。connect_ex()
方法尝试连接指定的主机和端口,并返回连接结果。- 最后,我们在
finally
块中确保无论成功与否都关闭socket连接,释放资源。
二、根据IP地址解析主机名
了解如何将IP地址转换为主机名是另一项重要的技能,特别是在调试网络问题时。我们同样可以通过socket
库来实现这一功能。以下是相关示例代码:
# 定义一个主机解析函数,参数为目标主机,目标端口(可以是多个)
def portScan(tgtHost, tgtPorts):
try:
tgtIP = gethostbyname(tgtHost)
except Exception as e:
print('[-] Cannot resolve \'%s\':Unknown host' %tgtHost)
return
try:
tgtName = gethostbyaddr(tgtIP)
print('\n[+] Scan Results for: ' + tgtName[0])
except Exception as e:
print('\n[+] Scan Results for: ' +tgtIP)
setdefaulttimeout(1)
for tgtPort in tgtPorts:
print('Scanning port ' + tgtPort)
connScan(tgtHost, int(tgtPort))
代码解析
gethostbyaddr()
方法根据IP地址返回对应的主机名及相关信息。- 我们同样在代码中使用了
try...except
结构,以捕获解析失败的情况并处理可能出现的异常。
三、整合上面两段代码
源码如下:
import optparse
import socket
from socket import *
def connScan(tgtHost, tgtPort):
try:
# 创建一个socket对象
connSkt = socket(AF_INET, SOCK_STREAM)
# 设置socket超时时间
connSkt.settimeout(1) # 设置为1秒
# 尝试连接到指定的主机和端口
result = connSkt.connect_ex((tgtHost, tgtPort))
# 如果返回值为0,说明端口开放
if result == 0:
print(f"端口 - {tgtPort} 在主机 {tgtHost} 上是开放的。")
else:
print(f"端口 - {tgtPort} 在主机 {tgtHost} 上是关闭的。")
except Exception as e:
print(f"发生异常:{e}")
finally:
connSkt.close()
def portScan(tgtHost, tgtPorts):
try:
tgtIP = gethostbyname(tgtHost)
except Exception as e:
print('[-] Cannot resolve \'%s\':Unknown host' %tgtHost)
return
try:
tgtName = gethostbyaddr(tgtIP)
print('\n[+] Scan Results for: ' + tgtName[0])
except Exception as e:
print('\n[+] Scan Results for: ' +tgtIP)
setdefaulttimeout(1)
for tgtPort in tgtPorts:
print('Scanning port ' + tgtPort)
connScan(tgtHost, int(tgtPort))
def main():
parser = optparse.OptionParser('usage %prog -H' + \
'<target host> -p <target port>')
parser.add_option('-H', dest='tgtHost', type='string', help='specify target host')
parser.add_option('-p', dest='tgtPort', type='string', help='specify target port[s] seperated by comma')
(options, args) = parser.parse_args()
tgtHost = options.tgtHost
tgtPorts = str(options.tgtPort).split(',')
if tgtHost == None or tgtPorts[0] == None:
print('[-] You must specify a target host and port[s].')
exit(0)
portScan(tgtHost, tgtPorts)
if __name__ == '__main__':
main()
运行结果如下:
(.venv) (base) liuxiaowei@localhost 运维 % python scanner.py -H 'www.baidu.com' -p '21,22,80'
[+] Scan Results for: 110.242.68.4
Scanning port 21
端口 - 21 在主机 www.baidu.com 上是关闭的。
Scanning port 22
端口 - 22 在主机 www.baidu.com 上是关闭的。
Scanning port 80
端口 - 80 在主机 www.baidu.com 上是开放的。
(.venv) (base) liuxiaowei@localhost 运维 % python scanner.py -H '192.168.1.23' -p '21,22,23,135,445'
[+] Scan Results for: localhost
Scanning port 21
端口 - 21 在主机 192.168.1.23 上是关闭的。
Scanning port 22
端口 - 22 在主机 192.168.1.23 上是开放的。
Scanning port 23
端口 - 23 在主机 192.168.1.23 上是关闭的。
Scanning port 135
端口 - 135 在主机 192.168.1.23 上是关闭的。
Scanning port 445
端口 - 445 在主机 192.168.1.23 上是关闭的。
总结
通过以上两个示例代码,我们可以看到使用Python进行网络编程是多么简单而高效。无论是检查端口状态还是根据IP地址进行反向解析,这些基本技能都是网络开发和运维过程中不可或缺的部分。希望本文能帮助您更好地理解和应用这些技术!
原创不易,欢迎点赞、关注、转发、收藏!!!