python網絡編程應用(一)

   在以前的一篇博客《python網絡編程基礎中介紹了socket.socket()函數及其應用,其實socket模塊中還有不少屬性可供網絡應用程序使用。這裏將詳細講解一下socket模塊中一些經常使用到的函數/屬性。html

 

  1. socket模塊屬性python

  下面列出了一些經常使用的socket模塊屬性。(引用自《python核心編程》)編程

 

  更詳細的函數說明,請看python官方文檔中的socket模塊:https://docs.python.org/2/library/socket.html網絡

 

   2. 實際應用中的實例分析socket

  2.1 打印設備名和IPV4地址tcp

  函數原型: socket.gethostname() 和 socket.gethostbyname(hostname) 。也可使用socket.getfqdn() 返回完整的域名字。函數

host_name = socket.gethostname()     # 獲取設備名

ip_addr = socket.gethostbyname(host_name)  # 獲取本機IP

remote_host = 'www.python.org'
ip_addr = socket.gethostbyname(remote_host)  # 獲取遠程主機的IP

  2.2 打印本地網絡接口的IPV4地址 post

import socket, fcntl, struct

ifname = "eth0"

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
inet = fcntl.ioctl(s.fileno(), 0x8915, struct.pack('256s', ifname[:15]))
ret = socket.inet_ntoa(inet[20:24])
print ret

   2.3 IPV4地址格式轉換spa

  函數原型:socket.inet_aton(ip_string 和socket.inet_ntoa(packed_ip) 。  若是須要ipv6支持,就須要使用inet_pton()/inet_ntop()函數。code

from binascii import hexlify  # 以十六進制形式表示二進制數據

ip_addr = '192.168.1.15'
packed_ip_addr = socket.inet_aton(ip_addr)  # 將字符串形式的IP地址轉換成32位二進制格式
unpacked_ip_addr = socket.inet_ntoa(packed_ip_addr) # 與上面相反
print "IP Address: %s" % ip_addr 
print "Packed: %s" % hexlify(packed_ip_addr)
print "Unpacked: %s" % unpacked_ip_addr

  2.4 經過指定端口和協議找服務名

  函數原型: socket.getservbyname(servicename[, protocolname])  和  socket.getservbyport(port[, protocolname]) 。協議名能夠省略,默認是找全部的協議,如需指定,只能是‘tcp’或者‘udp’。                   

serverport = socket.getservbyname('http','tcp')
servername = socket.getservbyport(80,'tcp')

  2.5 主機字節序與網絡字節序之間的轉換 

data = 1234

# 32-bit
print "Original: %s => Long host byte: %s => Network byte: %s" % (data,socket.ntohl(data),socket.htonl(data)
# 16-bit
print "Original: %s => Short host byte: %s => Network byte: %s" % (data,socket.ntohs(data),socket.htons(data)
## 函數名中的n表示網絡; h表示主機; l表示長整型; s表示短整型,即16位。 

  2.6 設置套接字超時

s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.settimeout(100)
print s.gettimeout()

  2.7 設置緩衝區大小

  setsockopt()方法接收三個參數:level、optname和value。其中,optname是選項名,value是該選項名的值。value所用的符號常量(SO_*等)能夠在socket模塊中查看。

import socket 

s_buf = 1024
r_buf = 1024

sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
bufsize = sock.getsockopt(socket.SOL_SOCKET,socket.SO_SNDBUF)
print "bufsize [Before]: %d" % bufsize

sock.setsockopt(socket.SOL_TCP, socket.TCP_NODELAY, 1)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF,s_buf)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF,r_buf)
bufsize = sock.getsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF)
print "bufsize [After]: %d" % bufsize

  2.8 設置套接字(非)阻塞模式

  默認狀況下,TCP套接字是處於阻塞模式下的。這種模式會使操做效率低下,若是兩個程序最後都在等待對方發送或者接收數據,就有可能致使死鎖。調用setblocking()方法能夠改變套接字的阻塞標誌。默認值爲1,表示會阻塞。傳入值爲0時則關閉阻塞。若是套接字爲非阻塞,而且沒有爲處理操做作好準備,就會產生一個socket.error。解決的方法是設置一個超時值。

s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.setblocking(1)
s.settimeout(0.5)
s.bind(('127.0.0.1',0))
socket_addr = s.getsockname()
print str(socket_addr)
while 1:
  s.listen(1) 

 2.9 地址重用

  當鏈接有意或無心關閉後,若是想再在這個端口上運行套接字服務端就會拋出一個"Address alreadly in use"異常。解決的方法是啓用套接字重用選項SO_REUSEADDR。

s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
 s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR, 1)
 s.bind((bind_ip, bind_port))
 s.listen(5)
    ...

  2.10 處理套接字錯誤

  在socket套接字使用過程當中,極可能會出現不少錯誤,可使用try-except語句處理異常。

# First try-except block
try:
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error, e:
    print "Error creating socket: %s" % e

# Second try-except block
try:
    s.connect((host, port))
except socket.gaierror, e:
    print "Address-related error connecting to server: %s" % e
    sys.exit(1)
except socket.error, e:
    print "Connection error: %s" % e
    sys.exit(1)

# Third try-except block
try:
    s.sendall("GET %s HTTP/1.0\r\n\r\n" % filename)
except socket.error, e:
    print "Error sending data: %s" % e
    sys.exit(1)

while 1:
    # Fourth try-except block
    try:
        buf = s.recv(1024)
    except socket.error, e:
        print "Error receiving data: %s" % e
        sys.exit(1)
相關文章
相關標籤/搜索