网络通信的基本接口是socket,它扩展了操作系统的基本I/O到网络网络通信。socket可以通过socket()函数来建立,通过connect()函数来连接。得到了socket,可以确定本地和远程端点的IP地址和端口号。socket对不同的协议来说都是一种通用的接口,它可以处理TCP和UDP通信。
建立socket需要两步:建立socket对象、连接到远程服务器上
importsocketprint "Creating socket"s=socket.socket(socket.AF_INET, socket.SOCK_STREAM) #指明通信类型和协议家族print "Done!"
print "Connecting to remote host..."s.connect(("www.baidu.com", 80))print "Done"
运行结果
Creating socket
Done!
Connecting to remote host...
Done
查找端口号
通过协议名和端口名查找端口号(unix系统可以在etc/services中找到对应的端口号)
importsocketprint "Creating socket"s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)print "Done!"
print "Looking up port number..."port= socket.getservbyname("http", "tcp")printportprint "done!"
print "Connecting to remote host..."s.connect(("www.baidu.com", port))print "Done!!"
运行结果
Creating socket
Done!
Looking up port number...
80
done!
Connecting to remote host...
Done!!
从socket获得信息
importsocketprint "Creating socket"s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)print "Done!"
print "Looking up port number..."port= socket.getservbyname("http", "tcp")printportprint "done!"
print "Connecting to remote host..."s.connect(("www.baidu.com", port))print "Done!!"
print "Connected from", s.getsockname() #获得本地机器的ip和端口号(端口号由操作系统随机分配,每次都不一样)print "Connected to", s.getpeername() #获得连接机器的ip和端口号
一次运行结果
Creating socket
Done!
Looking up port number...
80
done!
Connecting to remote host...
Done!!
Connected from ('192.168.209.129', 56245)
Connected to ('220.181.112.244', 80)
利用socket通信
socket对象:send()、sendto()、recv()、recvfrom()
文件类对象:read()、write()、readline()
处理错误
importsocket, sys
host= sys.argv[1]
textport= sys.argv[2]
filename= sys.argv[3]try:
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)exceptsocket.error, e:print "Strange error creating socket: %s" %e
sys.exit(1)try:
port=int(textport)exceptValueError:try:
port= socket.getservbyname(textport, 'tcp')exceptsocket.error, e:print "Couldn't find your port: %s" %e
sys.exit(1)try:
s.connect((host, port))exceptsocket.gaierror, e:print "Address-related error connecting to server: %s" %e
sys.exit(1)exceptsocket.error, e:print "Connection error: %s" %e
sys.exit(1)try:
s.sendall("GET %s HTTP/1.0\r\n\r\n" %filename)exceptsocket.error, e:print "Error sending data: %s" %e
sys.exit(1)print "---------------------------------------"
while 1:try:
buf= s.recv(2048)exceptsocket.error, e:print "========Error receving data: %s=======" %e
sys.exit(1)if notlen(buf):breaksys.stdout.write(buf)print "---------------------------------------"
改进
#coding: utf-8
importsocketimportsysimporttime
host= sys.argv[1]
textport= sys.argv[2]
filename= sys.argv[3]try:
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)exceptsocket.error, e:print "Strange error creating socket: %s" %e
sys.exit(1)try:
port=int(textport)exceptValueError:print "ValueError"
try:
port= socket.getservbyname(textport, 'tcp')exceptsocket.error, e:print "Couldn't find your port: %s" %e
sys.exit(1)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)print "Sleepping........."time.sleep(10)print "Continuing."
try:
s.sendall("GET %s HTTP/1.0\r\n\r\n" %filename)exceptsocket.error, e:print "Error sending data: %s" %e
sys.exit(1)try:
s.shutdown(1)exceptsocket.error, e:print "Error sending data (detected by shutdown):%s" %e
sys.exit(1)print "---------------------------------------"
while 1:try:
buf= s.recv(2048)print "try"
exceptsocket.error, e:print "========Error receving data: %s=======" %e
sys.exit(1)if not len(buf): #接受的为空
print "breaK"
breaksys.stdout.write(buf)print "---------------------------------------"