本文正在参加「Python主题月」,详情查看 活动链接。
在服务器上,很多时候需要观察端口的使用情况,当然我们可以使用成熟的工具
nmap
完成这个事情,但我们是不是可以用python
的socket
原生完成这件事情呢?
一、socket概念
我们很清楚,socket又称"套接字",socket套接字在 Internet 通信上广泛使用,应用程序通常通过"套接字"向网络发出请求或者应答网络请求,完成主机间或者一台计算机上的进程间的通讯。
python中的套接字模块提供对 BSD 套接字接口的访问。它包括用于处理实际数据通道的套接字类,以及用于与网络相关的任务的函数,例如将服务器名称转换为地址并格式化要通过网络发送的数据。
下图表达了使用socket通信的过程。
二、socket基本用法
我们先来熟悉一下socket函数的基本用法。在Python中,import socket
后,用socket.socket()
方法来创建套接字,语法格式如下:
socket = socket.socket([family[, type[, proto]]])
参数说明:
- family: 套接字家族,可以使
AF_UNIX
或者AF_INET
。 - type: 套接字类型,根据是面向连接的还是非连接分为
SOCK_STREAM
或SOCK_DGRAM
,也就是TCP和UDP的区别。 - protocol: 一般不填默认为0。
直接使用socket.socket() ,则全部使用默认值。
创建一个TCP套接字(流式)
socket=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
创建一个UDP套接字(数据报式)
socket=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
将一个主机名翻译成IPv4地址格式
gethostbyname("host")
将一个主机名翻译成IPv4地址格式,扩展接口
socket.gethostbyname_ex("host")
获取完全限定域名
socket.getfqdn("8.8.8.8")
获取机器的主机名
socket.gethostname()
异常处理
Exception handling
三、扫描端口实战
```
!/usr/bin/env python
import socket import subprocess import sys import platform from datetime import datetime
获取当前的系统类型,用不同的指令清空屏幕
if platform.system() == "Windows": subprocess.call('cls', shell=True) else: subprocess.call('clear', shell=True)
获取输入内容host
remoteServer = input("Enter a remote host to scan: ") remoteServerIP = socket.gethostbyname(remoteServer)
打印一个banner,打印格式如下
------------------------------------------------------------
Please wait, scanning remote host 110.242.68.3
------------------------------------------------------------
print ("-" * 60) print ("Please wait, scanning remote host", remoteServerIP) print ("-" * 60)
获取一个时间t1
t1 = datetime.now()
使用范围函数range()来指定端口(这里将扫描1到1024之间的所有端口)
针对异常,做了try..except 捕获处理
try: for port in range(1,1025): sock = socket.socket(socket.AFINET, socket.SOCKSTREAM) result = sock.connect_ex((remoteServerIP, port)) if result == 0: print ("Port {}: Open".format(port)) sock.close() except KeyboardInterrupt: print ("You pressed Ctrl+C") sys.exit() except socket.gaierror: print ('Hostname could not be resolved. Exiting') sys.exit() except socket.error: print ("Couldn't connect to server") sys.exit()
再次获取时间t2
t2 = datetime.now()
获取脚本计算的时间差
total = t2 - t1
打印时间差到控制台
print ('Scanning Completed in: ', total) ```