Chinaunix首页 | 论坛 | 博客
  • 博客访问: 245678
  • 博文数量: 68
  • 博客积分: 2802
  • 博客等级: 少校
  • 技术积分: 614
  • 用 户 组: 普通用户
  • 注册时间: 2010-01-11 15:38
文章存档

2013年(3)

2012年(15)

2011年(21)

2010年(29)

我的朋友

分类: LINUX

2011-11-01 14:48:13

转载来源:
编写客户端提交数据到服务器处理是程序员最常碰到的几个问题之一。各种不同的语言对此都有相应的解决方案。比如Unix下,C程序员们可以用 SUNRPC,Java程序员则使用RMI来处理。大多数语言还都可以使用Web Service或者ICE。它们的使用方法类似,编写一个接口定义文件,用一个工具处理并生成代码,加入到工程中,最后编译生成目标文件运行。有用过这类 工具的朋友们,脑子里应该都会闪出一个字——烦!真的是谁用谁知道。Python学习.` L}:J*D%z9\@

DP i!~j#@&Uv0Python同样也提供了一个基于XMLRPC的解决方案,不过用法很简单:Python学习/~?`y2Y po&k

;dZ.w$CE7Bg.e)OW;Q0首先,就好像在编写普通的程序那样子编写服务器。Python学习XT[sK L.{~

Python学习;@G5^sa i {5Y9p

接着使用SimpleXMLRPCServer模块运行XMLRPC服务器,在其中注册服务器提供的函数或者对象。

z-q7wI1\ u0

t(V2vi U QJ3FNY9Z oh0最后,在客户端内使用xmlrpclib.ServerProxy连接到服务器,想要调用服务器的函数,直接调用ServerProxy即可。

*r.Q? {&_0 Python学习QN?0HY\~

一个最简单的hello,word示例:

q o/Q6o:|-}1P[0 Python学习%J B-I6y$C

#helloserver.pyPython学习b E8qekJiH

Python学习&uAX2o~{1k

from SimpleXMLRPCServer import SimpleXMLRPCServer

def hello():

tp4W~\0 Python学习9Zz0t T}.A'Oprint "hello,world!"

svr=SimpleXMLRPCServer(("", 8080), allow_none=True)Python学习*y'V;_uwESDzc

4A&^0boN0svr.register_function(hello)

,nzv5xl1T E,x

_1n9]G5}P0svr.serve_forever()

9HB:VamqfE0 Python学习1D p0z#X V.Y&l6J

#helloclient.py

"cHKr.^/CJ B3Fs0 Python学习7`AP|M#M

from xmlrpclib import ServerProxyPython学习$z{%~ T!Vlhd

"M0m)[7q5X o)D8M|0svr=ServerProxy("")

C];A6~C/z U0

hl K:S0ci `x-}%m0svr.hello()Python学习 R#T8K-C E1sb4WJ&u

;]4P r$k#S"j;jG0先后运行helloserver.py和 helloclient.py就可以看到控制台输出hello,world

1T"N"u V;KmBI0

s2sJi3s'a5o.th&q0不过,美中不足的 是,SimpleXMLRPCServer是一个单线程的服务器。这意味着,如果几个客户端同时发出多个请求,其它的请求就必须等待第一个请求完成以后才 能继续。这里有个技巧解决这个问题:Python学习I4X?,RLq"B

-G8@&D-m*H!|X0from SimpleXMLRPCServer import SimpleXMLRPCServer

from SocketServer import ThreadingMixIn

class ThreadXMLRPCServer(ThreadingMixIn, SimpleXMLRPCServer):passPython学习Fo z)XF

6YDg)r9g"rY&_.Me0现在把helloserver改一改:Python学习{2i7W:y @,n ?X

Python学习%m`1Qy-t4Hr&]8@

svr=ThreadXMLRPCServer(("", 8080), allow_none=True)

4rs%r[]0 Python学习b%jGl$S we`6p

现在服务器就支持多线程并发了。Python学习%duF1V5f&L?2h I

.nw3?2KqY)G0XMLRPC一个标准协议,定义了如何使用HTTP和 XML来传递多种类型数据。据我观察,xmlrpclib对于日期/时间类型的有特殊的支持。假如有一个服务器提供的函数是:Python学习7b6[1nA O,P

Python学习'hx'x{%b,k9m

def toluar(d):pass

/Y u$V*BjQ0

*}!g)JV:| q\1h7^-N0这原本是一个将阳历转换成阴历的函数。要求d是 datetime模块里的datetime类型。虽然客户端确实传入的确实是datetime类型,服务器却会将其解释为 xmlrpclib.DateTime类型。 解决办法是:

H F x{CAbV0 Python学习Z[m/c*_ Oq U

class ThreadXMLRPCServer(ThreadingMixIn, SimpleXMLRPCServer):

CG|E;[0

ehfd$H}wG:i0#从SimpleXMLRPCServer模块抄出来的代码

dt5_3UwLA|MsQ!pj0 Python学习8mRv@0v

def _marshaled_dispatch(self, data, dispatch_method = None):

]-mvLhzW0 Python学习aw4tb5K|*O.[C

try:Python学习L y2Y\/K1\b2lt"U

Python学习]7qU.rl%R;P

params, method = xmlrpclib.loads(data,Python学习9X y!C8[ QZ

%C#CHvH5_ j0use_datetime=True) #这里加了一个use_datetime

8@v?#dvI A'^^0 Python学习,jH*k(p ]*Rq^"]&t

# generate response

j-@[AApb:E0

ayc7J-M wH `0V0if dispatch_method is not None:Python学习ACd/h%z

{3V8Y,L!N qa0response = dispatch_method(method, params)

!MP|3D.Ch]1l0 Python学习| B.y%Z*HIy

else:Python学习'f%V9h:wz t zq;_

%o }*eb1O v0response = self._dispatch(method, params)Python学习x;^\$cjYx

Python学习q.f%|O9p4x{ h

# wrap response in a singleton tuplePython学习*x S%K-U8X'X

)J:Lk V-a ?v#b0response = (response,)Python学习)B] I|Z3XLe

X7R[l;V6U0response = xmlrpclib.dumps(response,

e5kzc{0

8u6p1KOiY1j0methodresponse=1,

!eng9T7qy0

\3f5{ [/D%@7f0allow_none=self.allow_none,Python学习6\l|~y5|Ba

*}5Q0y ^kQ:A0encoding=self.encoding)

6QP)GE{'P0

{q:YMy1Cg,V^6k0except Fault, fault:Python学习u7Zw`3pd/Lj

!i[-`4v| |H6B c0response = xmlrpclib.dumps(fault, allow_none=self.allow_none,Python学习|A(V"z#zZh Wb

K;l@oP"A!th0encoding=self.encoding)Python学习6eOOVV2HF0a-o

zQ%|*r z"m h0except:Python学习 M1t1cL4zUA

Python学习w$hSu(L3T:f,C;V,e

# report exception back to serverPython学习(Si:O s.d/uU@ }}

Python学习w XQ&C It-k3s

exc_type, exc_value, exc_tb = sys.exc_info()

;NQ*K x8n ^/R0

}.v'vj` dT0response = xmlrpclib.dumps(xmlrpclib.Fault(1, "%s:%s" % (exc_type, exc_value)),encoding=self.encoding, allow_none=self.allow_none,)Python学习6m0c MU~z{7P iX)I

j*mt0m D9gk_0return responsePython学习 ^1m%l k'~#?

Python学习SI$\ v$]J3r

svr=ThreadXMLRPCServer(("", 8080), allow_none=True)

b6Q~@wr?k,y0 Python学习#Z8B*P}u3a }Gf

客户端方面则比较简单:

[ K t"t;p qc0

-Z2Tr C1T8c"H7[$s0svr=ServerProxy("/", allow_none=True, use_datetime=True)

:G&ecu,lg0z*z0

,I\g-IJ'zL&t,N0注意 use_datetime参 数默认是False


8F)kB n }5m
阅读(6146) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~