网络通信
网络上寻找主机
import socket print socket.gethostname()
使用gethostbyname()访问操作系统主机名解析API,将服务器名字转换为其数字地址。
import socket for host in ['homer','www','www.python.org','nosuchname']: try: print "%s:%s" % (host,socket.gethostbyname(host)) except socket.error, msg: print "%s:%s" % (host,msg)
使用gethostbyname_ex(),返回服务器的标准主机名/所有别名/以及所有ip地址。
import socket for host in ['homer','www','www.python.org','nosuchname']: print host try: hostname,aliases,addresses = socket.gethostbyname_ex(host) print 'hostname:',hostname print 'aliases:',aliases print 'addresses:',addresses except socket.error as msg: print 'ERROR:',msg print
如果得到一个服务器地址,通过gethostbyaddr()可以用来逆向查找得到主机名。(只有本地可行...why)
import socket hostname,aliases,addresses = socket.gethostbyaddr('192.168.0.100') print 'Hostname:',hostname print 'Aliases:',aliases print 'Addresses:',addresses
通过getservbyname()查找服务信息/端口
import socket from urlparse import urlparse for url in ['http://www.python.org', 'https://www.mybank.com', 'ftp://prep.ai.mit.edu', 'gopher://gopher.micro.umn.edu', 'smtp://mail.example.com', 'imap://mail.example.com', 'imaps://mail.example.com', 'pop3://pop.example.com', 'pop3s://pop.example.com', ]: parsed_url = urlparse(url) port = socket.getservbyname(parsed_url.scheme) print '%s:%s' % (parsed_url,port)
通过getservbyport()逆向查找端口(匹配法)。
可以使用gtprotobyname()获取分配给一个传输协议的端口号。
查找服务器地址
getaddrinfo()将基本地址转换为一个元组列表,其中包含建立一个连接所需的全部信息。
import socket def get_constants(prefix): return dict( (getattr(socket,n),n) for n in dir(socket) if n.startswith(prefix) ) families = get_constants('AF_') types = get_constants('SOCK_') protocols = get_constants('IPPROTO_') for response in socket.getaddrinfo('www.python.org','http'): family,socktype,proto,canonname,sockaddr = response print 'Family:',families[family] print 'Type:',types[socktype] print 'Protocol:',protocols[proto] print 'Canonical name:',canonname print 'Socket Address',sockaddr print
TCP/IP服务端和客户端
服务端:创建套接字->bind()->listen()->accept()
客户端:创建套接字->connect()->sendall()
服务端
import socket import sys #创建一个套接字 sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM) #bind()将套接字与服务器地址关联 server_address = ('localhost',9999) print >>sys.stderr,'starting up om %s port %s' % server_address sock.bind(server_address) #调用listen()将套接字置为服务器模式,调用accept()等待到来的连接 sock.listen(1) while True: print >> sys.stderr,'waiting for a connection.' connection,client_address = sock.accept() #xxx try: print >>sys.stderr,'connection from',client_address while True: data = connection.recv(16) print >>sys.stderr,'received "%s"' % data if data: print >>sys.stderr,'sending data back to the client' connection.sendall(data) else: print >>sys.stderr,'no data from',client_address break finally: connection.close()
客户端
import socket import sys #创建一个TCP/IP套接字 sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM) #连接这个套接字到正在等待回应的服务器 server_address = ('localhost',9999) print >>sys.stderr,'connecttin to %s port %s' % server_address sock.connect(server_address) #连接上后,传输数据 try: #传送数据 message = 'there is p0pl4r,who are u?' print >>sys.stderr,'sending %s' % message sock.sendall(message) #等待回应 amount_received = 0 amount_expected = len(message) while amount_received < amount_expected: data = sock.recv(16) amount_received += len(data) print >>sys.stderr,'received "%s"' % data finally: print >>sys.stderr,'closing socket.byebye' sock.close()
使用Python搭建HTTP PUT服务器
代码以下保存到HTTPutServer.py文件里: # ref: https://www.snip2code.com/Snippet/905666/Python-HTTP-PUT-test-server import sys import signal from threading import Thread from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler class PUTHandler(BaseHTTPRequestHandler): def do_PUT(self): length = int(self.headers['Content-Length']) content = self.rfile.read(length) self.send_response(200) with open(self.path[1:], "w") as f: f.write(content) def run_on(port): print("Starting a HTTP PUT Server on {0} port {1} (http://{0}:{1}) ...".format(sys.argv[1], port)) server_address = (sys.argv[1], port) httpd = HTTPServer(server_address, PUTHandler) httpd.serve_forever() if __name__ == "__main__": if len(sys.argv) < 3: print("Usage:\n\tpython {0} ip 1337".format(sys.argv[0])) sys.exit(1) ports = [int(arg) for arg in sys.argv[2:]] try: for port_number in ports: server = Thread(target=run_on, args=[port_number]) server.daemon = True # Do not make us wait for you to exit server.start() signal.pause() # Wait for interrupt signal, e.g. KeyboardInterrupt except KeyboardInterrupt: print "\nPython HTTP PUT Server Stoped." sys.exit(1) 运行方法: $ python HTTPutServer.py 10.10.10.100 1337 Starting a HTTP PUT Server on 10.10.10.100 port 1337 (http://10.10.10.100:1337) ...