标签:
在开始python网络编程之前,首先要了解一下套接字,套接字是一种计算机网络数据结构。套接字有两种,分别是基于文件型的和基于网络型的,前者如AF_UNIX,后者如AF_INET、AF_NETLINK。套接字端口就像电话号码一样,是通讯身份的唯一标识,合法的端口号范围为0到65535,其中,小于1024的端口号为系统保留端口,如果是Unix操作系统,保留的端口号使用可以通过/etc/services文件获得。
套接字的类型有两种,面向连接的套接字与无连接的套接字。前者提供了顺序的、可靠的、不会重复的数据传输,而且也不会加上数据边界,每一个要发送的信息,可能会被拆成多份,实现这种连接的主要协议就是传输控制协议TCP,套接字类型为SOCK_STREAM,使用IP来查找网络中的主机,这样就形成了整个系统。无连接的套接字,数据到达的顺序、可靠性及数据不重复性无法保证,数据报会保留数据边界,发送消息时不会拆成小块,虽有这么多缺点,但正是无连接的,所以不需要承担维持虚电路连接的负担,性能更好,实现这种连接的主要协议是用户数据报协议UDP,套接字类型为SOCK_DGRAM,也是通过IP来查找网络中的主机。
python网络编程使用socket模块,创建套接字用其socket()函数,语法如下:
socket(socket_family, socket_type, protocol = 0)
socket_family可以是AF_UNIX或AF_INET,socket_type可以是SOCK_STREAM或SOCK_DGRAM,protocol一般不写,默认为0。
当我们创建了套接字以后,所有的交互都将通过对该套接字对象的方法调用进行,下面列举一些套接字对象的常用函数。
服务器端——
bind():绑定地址到套接字。
listen():开始TCP监听。
accept():被动接受TCP客户的连接,阻塞式等待连接的到来。
客户端——
connect():主动初始化TCP服务器连接。
connect_ex():上一个函数的扩展版本,出错时返回出错码,而不是抛出异常。
公共用途——
recv():接收TCP数据。
send():发送TCP数据。
sendall():完整发送TCP数据。
recvfrom():接收UDP数据。
sendto():发送UDP数据。
getpeername():连接到当前套接字的远端的地址。
getsockname():当前套接字的地址。
getsockopt():返回指定套接字的参数。
setsockopt():设置指定套接字的参数。
close():关闭套接字。
阻塞相关——
setblocking():设置套接字的阻塞与非阻塞模式。
settimeout():设置阻塞套接字操作的超时时间。
gettimetout():得到阻塞套接字操作的超时时间。
面向文件——
fileno():套接字的文件描述符。
makefile():创建一个与该套接字关联的文件。
下面是TCP服务器的伪代码——
ss = socket()#创建服务器套接字
ss.bind()#把地址绑定到套接字上
ss.listen()#监听连接
inf_loop:#服务器无限循环
cs = ss.accept()#接收客户的连接
comm_loop:#通讯循环
cs.recv()/cs.send()#对话,接收与发送
cs.close()#关闭客户套接字
ss.close()#关闭服务器套接字,可选
下面是TCP客户端的伪代码——
cs = socket()#创建客户套接字
cs.connect()#尝试连接服务器
comm_loop:#通讯循环
cs.send()/cs.recv ()#对话,发送与接收
cs.close()#关闭客户套接字
下面以一个简单的例子作为介绍,服务器、客户端在同一台机子上,服务器充当时间戳的角色,客户端发送数据后返回一个带时间的相同数据。
TimeServer.py——
#!/usr/bin/env python
from socket import *
from time import ctime
HOST = ‘‘ # any available
PORT = 21567 # unused
BUFSIZE = 1024
ADDR = (HOST, PORT)
tcpSerSock = socket(AF_INET, SOCK_STREAM)
tcpSerSock.bind(ADDR)
tcpSerSock.listen(5) # max concurrence access
while True:
print ‘waiting for connection...‘
tcpCliSock, addr = tcpSerSock.accept() # blocking and passive
print ‘...connected from: ‘, addr
while True:
data = tcpCliSock.recv(BUFSIZE)
if not data:
break
tcpCliSock.send(‘[%s] %s‘ %(ctime(), data) )
tcpCliSock.close()
tcpSerSock.close() # optional and never exec
TimeClient.py——
#!/usr/bin/env python
from socket import *
HOST = ‘localhost‘ # local host
PORT = 21567 # the same port as the server
BUFSIZE = 1024
ADDR = (HOST, PORT)
tc#!/usr/bin/env python
from socket import *
pCliSock = socket(AF_INET, SOCK_STREAM)
tcpCliSock.connect(ADDR)
while True:
data = raw_input(‘> ‘)
if not data:
break
tcpCliSock.send(data)
data = tcpCliSock.recv(BUFSIZE)
if not data:
break
print data
tcpCliSock.close()
UDP相对TCP来说比较简单,因为是无连接的,所以服务端不需要listen和accept,客户端也不需要connect。
下面是UDP服务器的伪代码——
ss = socket()
ss.bind()#把地址绑定到套接字上
inf_loop:#服务器无限循环
cs.recvfrom()/cs.sendto()#对话,接收与发送
ss.close()#关闭服务器套接字,可选
下面是UDP客户端的伪代码——
cs = socket()#创建客户套接字
comm_loop:#通讯循环
cs.sendto()/cs.recvfrom ()#对话,发送与接收
cs.close()#关闭客户套接字
SocketServer模块是一个基于socket模块的高级别的套接字通讯模块,它支持在新的线程或进程中处理客户的请求。这个模块是标准库中一个高级别的模块,用于简化网络客户与服务器的实现,模块中已经实现了一些可供使用的类。下面用SocketServer实现上面的例子,即时间戳服务器。
timeSSSer.py——
#!/usr/bin/env python
from SocketServer import (TCPServer as TCP, StreamRequestHandler as SRH)
from time import ctime
HOST = ‘‘
PORT = 21567
ADDR = (HOST, PORT)
class MyRequestHandler(SRH):
def handler(self):
print ‘... connected from:‘, self.client_address
self.wfile.write(‘[%s] %s‘) %(ctime(), self.rfile.readline())
tcpServ = TCP(ADDR, MyRequestHandler)
print ‘waiting for connection...‘
tcpServ.serve_forever()
timeSSCli.py——
#!/usr/bin/env python
from socket import *
HOST = ‘localhost‘
PORT = 21567
BUFSIZE = 1024
ADDR = (HOST, PORT)
while True:
tcpCliSock = socket(AF_INET, SOCK_STREAM) # socket every time
tcpCliSock.connect(ADDR)
data = raw_input(‘> ‘)
if not data:
break
tcpCliSock.send(‘%s\r\n‘ %data)
data = tcpCliSock.recv(BUFSIZE)
if not data:
break
print data.strip()
tcpCliSock.close()
其它——
twisted模块是一个完全事件驱动的网络框架,可以用来开发完全异布的网络应用程序和协议,创建一个完整的系统,系统中可以有网络协议、线程、安全认证、即时通讯、数据库管理、网页、电子邮件、命令行参数、图形界面集成等。下面使用twisted模块实现上面例子中同样的功能。
timeTSSer.py——
#!/usr/bin/env python
from twisted.internet import protocol, reactor
from time import ctime
PORT = 21567
class TSServProtocol(protocol.Protocol):
def connectionMade(self):
self.clnt = self.transport.getPeer().host
print ‘...connected from:‘, self.clnt
def dataReceived(self, data):
print ‘...received from [%s]\n\t%s‘ %(self.clnt, data)
self.transport.write(‘[%s] %s‘ %(ctime(), data))
factory = protocol.Factory()
factory.protocol = TSServProtocol
print ‘waiting for connection...‘
reactor.listenTCP(PORT, factory)
reactor.run()
timeTSCli.py——
#!/usr/bin/env python
from twisted.internet import protocol, reactor
HOST = ‘localhost‘
PORT = 21567
class TSClntProtocol(protocol.Protocol):
def sendData(self):
data = raw_input(‘> ‘)
if data:
print ‘...sending %s...‘ %data
self.transport.write(data)
else:
self.transport.loseConnection()
def connectionMade(self):
self.sendData()
def dataReceived(self, data):
print data
self.sendData()
factory = protocol.ClientFactory()
factory.protocol = TSClntProtocol
reactor.connectTCP(HOST, PORT, factory)
reactor.run()
asyncore/asynchat模块,为能异步处理客户请求的网络应用程序提供底层功能。
select模块,在单线程网络服务器程序中,管理多个套接字连接。
标签:
原文地址:http://blog.csdn.net/ieearth/article/details/46410933