Python的socket模块为操作系统的socket实现提供了一个python接口。
In [168]: import socket In [169]: s=socket.socket() In [170]: s.connect(("127.0.0.1",80)) In [171]: s.send("GET / HTTP/1.1\n\n") Out[171]: 16 In [172]: s.recv(200) Out[172]: 'HTTP/1.1 400 Bad Request\r\nServer: nginx\r\nDate: Mon, 21 Jul 2014 02:34:14 GMT\r\nContent-Type: text/html\r\nContent-Length: 166\r\nConnection: close\r\n\r\n<html>\r\n<head><title>400 Bad Request</title></head>\r\n<b' In [173]: s.close()
先创建一个名为s的socket对象,然后连接到本地的Nginx服务器,这里要注意一下connect只能带一个参数,如果是IP和端口对需要用括号括住。然后通过send()函数发送一个HTTP请求,然后接收服务端响应的前200个字节。最后关闭socket连接
#/usr/bin/python import socket import re import sys def check_server(address, port): s=socket.socket() print "Attempting to connect to %s on port %s" %(address,port) try: s.connect((address,port)) print "Connected to %s on port %s" %(address,port) return True except socket.error,e: print "Connection to %s on port %s failed: %s" %(address,port,e) return False if __name__ == '__main__': from optparse import OptionParser parser = OptionParser() parser.add_option("-a", "--address", dest="address",default='localhost', help="Address for the server", metavar="ADDRESS") parser.add_option("-p", "--port", dest="port",type="int", default=80,help="PORT for server",metavar="PORT") (options, args) = parser.parse_args() print 'options: %s,args: %s' %(options,args) check=check_server(options.address,options.port) print 'check server returned %s' %check sys.exit(not check)
以上程序用于探测远程主机的端口状态,通过socket的connect()函数去尝试连接远程主机的给定端口。后面主要用到optparse模块添加选项。
$ python tcp_port_checker.py -a 10.10.41.20 -p 80 options: {'port': 80, 'address': '10.10.41.20'},args: [] Attempting to connect to 10.10.41.20 on port 80 Connected to 10.10.41.20 on port 80 check server returned True $ python tcp_port_checker.py -a 10.10.41.20 -p 80 && echo "SUCCESS" options: {'port': 80, 'address': '10.10.41.20'},args: [] Attempting to connect to 10.10.41.20 on port 80 Connected to 10.10.41.20 on port 80 check server returned True SUCCESS $ python tcp_port_checker.py -a 10.10.41.20 -p 81 || echo "FAILURE" options: {'port': 81, 'address': '10.10.41.20'},args: [] Attempting to connect to 10.10.41.20 on port 81 Connection to 10.10.41.20 on port 81 failed: [Errno 111] Connection refused check server returned False FAILURE
一个web server的80端口开放并不能代表这台服务器上就运行着web服务,还需要通过HTTP响应返回值来判断。
#/usr/bin/python import socket import re import sys def check_webserver(address,port,resource): if not resource.startswith('/'): resource = '/' + resource request_string = "GET %s HTTP/1.1\r\nHost: %s\r\n\r\n" %(resource,address) print 'HTTP request:' print '|||%s|||' %request_string s=socket.socket() print "Attempting to connect to %s on port %s" %(address,port) try: s.connect((address,port)) print "Connected to %s on port %s" %(address,port) s.send(request_string) rsp=s.recv(100) print "Received 100 bytes of HTTP response" print '|||%s|||' %rsp except socket.error,e: print "Connection to %s on port %s failed: %s" %(address,port,e) print "Closing the connection" s.close() lines=rsp.splitlines() print "First line of HTTP response: %s" %lines[0] try: version,status,message=re.split(r'\s+',lines[0],2) print 'Version: %s, Status: %s, Message: %s' %(version,status,message) except ValueError: print 'Failed to split status line' return False if status in ['200','301']: print 'Success - status was %s' %status return True else: print 'Status was %s' %status return False if __name__ == '__main__': from optparse import OptionParser parser = OptionParser() parser.add_option("-a","--address",dest="address",default='localhost',help="ADDRESS for webserver",metavar="ADDRESS") parser.add_option("-p","--port",dest="port",type="int",default=80,help="PORT for webserver",metavar="PORT") parser.add_option("-r","--resource",dest="resource",default='index.html',help="RESOURCE for webserver",metavar="RESOURCE") (options,args)=parser.parse_args() print 'options: %s,args: %s' %(options,args) check=check_webserver(options.address,options.port,options.resource) print 'check_webserver returned %s' %check sys.exit(not check)
以上程序主要通过check_webserver函数去探测HTTP服务,检测端口是否可以连接,并发送HTTP请求,通过web server的返回值进行判断。
$ python tcp_port_checker2.py -a 10.10.41.20 -p 80 -r index.php options: {'resource': 'index.php', 'port': 80, 'address': '10.10.41.20'},args: [] HTTP request: |||GET /index.php HTTP/1.1 Host: 10.10.41.20 ||| Attempting to connect to 10.10.41.20 on port 80 Connected to 10.10.41.20 on port 80 Received 100 bytes of HTTP response |||HTTP/1.1 404 Not Found Server: nginx Date: Tue, 22 Jul 2014 03:24:17 GMT |||tent-Type: text/html Closing the connection First line of HTTP response: HTTP/1.1 404 Not Found Version: HTTP/1.1, Status: 404, Message: Not Found Status was 404 check_webserver returned False