注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

蜻蜓点水 举重若轻

君子终日乾乾

 
 
 

日志

 
 

[Python 技术培训] 第三周讲义

2006-10-31 12:24:15|  分类: Python |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
  今天是网络编程。不妨做一个即时聊天工具吧, 不过这次的程序很简陋, 只能说是一个网络对讲机罢了。


  今天我不准备去讲更底层的东西, 比如使用 Socket 来编写通信程序。不过以后, 可能就是下次我们就会涉及到。


  然而, 今天的东西相当有用。在没有必要钻牛角尖的时候 (这是大多数的情况), 今天所用到的方法几乎是第一选择。使用 XMLRPC 来进行网络编程, 确实出奇的简单。但是请注意, 千万不要被现在国内的风气给误导了, 其实使用简单的工具来进行编程并不愚蠢, 相反是你聪明的表现。而且, 复杂的应用通常是用最简单的方法建立的, 如果妄图使用石器时代的工具来建造高楼大厦, 那几乎是不可能的。


  下面先来个服务器。

  from SimpleXMLRPCServer import SimpleXMLRPCServer

  def foo():
    return "Hello world!"

  server = SimpleXMLRPCServer( ("localhost", 8000) )
  server.register_function(foo)
  server.serve_forever()


  用 IE 来访问 http://localhost:8000 看看我们得到了什么? 是一个出错页面, 不错, 这表示我们的服务器工作正常, 只是访问的方法不对而已。


  下面, 给出这个程序的客户机程序。

  from xmlrpclib import ServerProxy
  server = ServerProxy("http://localhost:8000")
  print server.foo()


  我们会看到服务器返回了 "Hello world!"。这里 localhost 是指本机, 8000 是端口, 我们通常会指定大于 1024 的端口号。localhost 我们通常会用域名 (机器名) 或 IP 来代替, 而端口号是任意的。


  下面, 该传些东西了。比如发送一句话到服务器上去显示出来。

  from SimpleXMLRPCServer import SimpleXMLRPCServer

  def msg(s):
    print s
    return True

  server = SimpleXMLRPCServer( ("localhost", 8000) )
  server.register_function(msg)
  server.serve_forever()


  对应的客户机程序。

  from xmlrpclib import ServerProxy
  server = ServerProxy("http://localhost:8000")

  while True:
    msg = raw_input()
    server.msg(msg)


  开个玩笑, 一个即时通信工具已经写好了。两台机器互相知道 IP 或者机器名, 协商好端口号。然后打开一个服务器、将客户机指向对方的服务器就可以了。


  那么怎么将客户端和服务器合并在一起呢? 因为调用 serve_forever() 之后程序就停在那里了, 所以无法再接收用户输入的东西了。这里顺便讲一下多线程编程, 但是这个话题不在本次主题之内, 大家仅做理解就可以了。

  import thread
  from SimpleXMLRPCServer import SimpleXMLRPCServer
  from xmlrpclib import ServerProxy

  def msg(s):
    print s
    return True

  def run_server():
    my_server = SimpleXMLRPCServer( ("localhost", 8001) )
    my_server.register_function(msg)
    my_server.serve_forever()

  def run_client():
    your_server = ServerProxy("http://localhost:8002")
    while True:
      msg = raw_input()
      your_server.msg(msg)

  thread.start_new_thread( run_server, () )
  run_client()


  第二个差不多, 只是把互相的地址换了一下而已。

  import thread
  from SimpleXMLRPCServer import SimpleXMLRPCServer
  from xmlrpclib import ServerProxy

  def msg(s):
    print s
    return True

  def run_server():
    my_server = SimpleXMLRPCServer( ("localhost", 8002) )
    my_server.register_function(msg)
    my_server.serve_forever()

  def run_client():
    your_server = ServerProxy("http://localhost:8001")
    while True:
      msg = raw_input()
      your_server.msg(msg)

  thread.start_new_thread( run_server, () )
  run_client()


  这样, 一对对讲机就写好了。


  接下来就要用到我上一次讲到的图形界面的知识, 用 Tkinter 来写一个界面了。


  首先把窗体画出来。

  from Tkinter import *
  wnd = Tk()
  wnd.lab = Label(wnd, text="---")
  wnd.ent = Entry(wnd)
  wnd.btn = Button(wnd, text="send")
  wnd.lab.pack()
  wnd.ent.pack(side=LEFT)
  wnd.btn.pack(side=LEFT)


  然后把刚才的网络部分加上去。

  import thread
  from SimpleXMLRPCServer import SimpleXMLRPCServer
  from xmlrpclib import ServerProxy

  # 第一个对讲机
  my_server   = SimpleXMLRPCServer( ("localhost", 8002) )
  your_server = ServerProxy("http://localhost:8001")

  # 第二个对讲机 (需要交换一下地址)
  # my_server   = SimpleXMLRPCServer( ("localhost", 8001) )
  # your_server = ServerProxy("http://localhost:8002")


  def msg(s):
    wnd.lab.config(text=s)
    return True

  def run_server():
    my_server.register_function(msg)
    my_server.serve_forever()

  def send():
    msg = wnd.ent.get()
    wnd.ent.select_range(0, len(msg))
    your_server.msg(msg) 

  wnd.btn.config(command=send)

  thread.start_new_thread( run_server, () )
  wnd.mainloop()

  因为程序比较长, 所以另外一个终端就不写了。注意, 这里两台终端的地址是在程序中写死的。而且现在的程序只能显示最近收到的一条消息。

  ·我们可以使用 Tkinter 中的输入框来叫用户自己输入目标机器的地址和端口。
  ·我们可以使用 Tkinter 中的编辑框组件来显示多行消息。

  这个作为这次的作业。我的意思是完善这个聊天程序, 做成比较漂亮的样子。同时思考一下如何来实现一个多人聊天室。

  下周可能会涉及到 Socket, 请预习一下。
  评论这张
 
阅读(3838)| 评论(1)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017