python网络编程应用(一)

这里将详细讲解一下socket模块中一些常用到的函数/属性。

 

  1. socket模块属性

  下面列出了一些常用的socket模块属性。(引用自《python核心编程》)

 

  更详细的函数说明,请看python官方文档中的socket模块:https://docs.python.org/2/library/socket.html

 

   2. 实际应用中的实例分析

  2.1 打印设备名和IPV4地址

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

1
2
3
4
5
6
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地址 

1
2
3
4
5
6
7
8
import  socket, fcntl, struct
 
ifname  =  "eth0"
 
=  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地址格式转换

  函数原型:socket.inet_aton(ip_string 和socket.inet_ntoa(packed_ip) 。  如果需要ipv6支持,就需要使用inet_pton()/inet_ntop()函数。

1
2
3
4
5
6
7
8
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’。                   

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

  2.5 主机字节序与网络字节序之间的转换 

1
2
3
4
5
6
7
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 设置套接字超时

1
2
3
=  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模块中查看。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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。解决的方法是设置一个超时值。

1
2
3
4
5
6
7
8
=  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。

1
2
3
4
5
=  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语句处理异常。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# First try-except block
try :
     =  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 )

  

标签:  python学习笔记
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值