您的位置:首页 > 理论基础 > 计算机网络

python网络编程

2015-06-08 12:28 471 查看
在开始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模块,在单线程网络服务器程序中,管理多个套接字连接。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: