第2章 网络客户端
网络客户端开发步骤:
1、 建立socket对象。
2、 调用connect()建立连接 。
2.1 建立Socket
import socket
print "Creating socket...."
# socket.socket(协议,通讯方式) 创建socket对象
# socket.AF_INET使用PIV4协议;
# socket.SOCK_STREAM TCP通讯方式
# socket.SOCK_DGTAM UDP通讯方式
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print 'Done'
print 'Connecting to remote host...'
# 连接服务器: IP,port
s.connect(("10.10.151.70", 8080))
print 'done.'
2.2 寻找端口号
import socket
print 'Create socket...'
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print 'done'
print 'Looking up port number...'
# 通过socket的getservbyname()函数查询端口号
port = socket.getservbyname('http', 'tcp')
print 'done.'
print 'Connecting to remote host on port %d...' % port
s.connect(('www.google.com', port))
print 'done.'
2.3 获取socket信息
import socket
print 'Creating socket...'
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print 'done.'
s.connect(('localhost', 8080))
print 'done.'
# 显示本机的IP地址和端口号
print 'Connected from', s.getsockname()
# 显示远端服务器的IP地址和端口号
print 'Connected to ', s.getpeername()
2.4 socket通信
Socket通讯Python提供了2中方式:socket对象和文件类对象。
1、 socket对象:send()、sendto()、recv()、recvfrom()等方法。
2、 文件类对象:read()、write()、readline()。
Socket对象适用范围:
读写数据时,需要协议详细控制时、使用二进制协议传送固定大小数据时、数据超时处理时还有编写UDP程序时,socket对象都是很好的选择。
文件类对象适用范围:用于面向线性的协议,他能通过提供的readline()函数自动处理大多数解析,但是对于UDP协议支持不好。
2.4.1 Socket对象实例
import socket, sys
host = sys.argv[1] #主机IP
textport = sys.argv[2] #端口号
filename = sys.argv[3] #服务器文件名称
#建立socket对象
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error, e:
print 'Strange error creating socket:%s' % e
sys.exit(1)
#解析端口号
try:
port = int(textport)
except ValueError:
try:
port = socket.getservbyname(textport, 'tcp')
except socket.error, e:
print 'Couldn not 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)
#发送文件
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)
#清除缓存内容
try:
s.shutdown(1)
except socket.error, e:
print 'Error sending data:%s' % e
sys.exit(1)
while True:
try:
buf = s.recv(2048) #接收数据
except socket.error, e:
print 'Error receiving data:%s' % e
sys.exit(1)
if not len(buf):
break
sys.stdout.write(buf)
2.4.2 文件类对象实例
i
mport socket, sys, time
host = sys.argv[1]
textport = sys.argv[2]
filename = sys.argv[3]
#创建socket对象
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error, e:
print 'Strange error creating socket:%s' % e
sys.exit(1)
#创建端口号
try:
port = int(textport)
except ValueError:
try:
port = socket.getservbyname(textport, 'tcp')
except socket.error, e:
print 'Couldn not find your port:%s' % e
sys.exit(1)
#连接socket
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)
fd = s.makefile('rw', 0) #使用文件类对象
print 'sleeping...'
time.sleep(10) #线程休息10S
print 'Continuing...'
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)
try:
fd.flush()
except socket.error, e:
print 'Error sending data: %s' % e
sys.exit(1)
try:
s.shutdown(1)
s.close()
except socket.error, e:
print 'Error sending data:%s' % e
while True:
try:
buf = fd.read(2048)
except socket.error, e:
print 'Error receiving data:%s' % e
sys.exit(1)
if not len(buf):
break
sys.stdout.write(buf)
2.5 UDP通信
UDP通信不使用文件类对象,因为他不能为数据如何发送和接收提供足够的控制。
import socket, sys
host = sys.argv[1]
textport = sys.argv[2]
# 使用SOCK_DGRAM 报文
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
try:
port = int(textport)
except ValueError:
# 使用UDP协议
port = socket.getservbyname(textport, 'udp')
s.connect((host, port))
print 'Enter data to transmit:'
data = sys.stdin.readline().strip()
s.sendall(data)
print 'Looking for replies; press Ctrl-C or Ctrl-Break to stop.'
while True:
buf = s.recv(2048)
if not len(buf):
break
sys.stdout.write(buf)