Python 创建一个 UDP 服务

由于 UDP 服务器不是面向连接的,所以不用像 TCP 服务器那样做那么多设置工作。事实上,并 不用设置什么东西,直接等待进来的连接就好了。
ss = socket() #创建一个服务器套接字
ss.bind() #绑定服务器套接字
inf_loop: #服务器无限循环
cs = ss.recvfrom()/ss.sendto() # 对话(接收与发送)
ss.close() # 关闭服务器套接字
从伪代码中可以看出,使用的还是那套先创建套接字然后绑定到本地地址(主机/端口对)的方法。无限循环中包含了从客户那接收消息,返回加了时间戳的结果和回去等下一个消息这三步。 同样的,由于代码不会跳出无限循环,所以,close()函数调用是可选的。我们写这一句话的原因是 要提醒读者,在设计一个更智能的退出方案的时候,要确保 close()函数会被调用。
#coding=utf-8
#UDP时间戳服务器(tsUserv.py)

from socket import *
from time import ctime
HOST = ''
PORT = 10086
BUFSIZ = 1024
ADDR = (HOST,PORT)

udpSerSock = socket(AF_INET,SOCK_DGRAM)
udpSerSock.bind(ADDR)

while True:
print 'waiting for message...'
data,addr = udpSerSock.recvfrom(BUFSIZ)
udpSerSock.sendto('[%s] %s' % (ctime(), data),addr)
print '...received from and returned to:',addr
udpSerSock.close()


UDP 和 TCP 服务器的另一个重要的区别是,由于数据报套接字是无连接的,所以无法把客户的连 接交给另外的套接字进行后续的通讯。这些服务器只是接受消息,需要的话,给客户返回一个结果 就可以了。

例 16.3 的 tsUserv.py 是之前那个 TCP 服务器的 UDP 版本,它接收客户的消息,加时间戳后返 回给客户。
逐行解释
1-4 行
就像 TCP 服务器的设置那样,在 Unix 的启动信息行后,我们导入了 time.ctime()函数和 socket
模块的所有属性。
6-12 行
HOST 和 PORT 变量与之前完全一样。socket()函数的调用有一些不同,我们现在要的是一个数据 报/UDP 的套接字类型。不过 bind()函数还是跟 TCP 版本的一样。同样地,由于 UDP 是无连接的,就 不用调用 listen()函数来监听进来的连接了。
14-21 行
在进入到服务器的无限循环后,我们(被动地)等待(数据报)消息的到来。当有消息进来时,就 处理它(在前面加时间戳),把结果返回回去,然后再去等等下一个消息。就像之前一样,那个 close() 函数只是一个演示而已。


16.3.7 创建一个 UDP 客户端
这一节中介绍的 4 段程序中,下面的这段 UDP 客户的代码是最短的。伪代码如下:
cs = socket() # 创建客户套接字 comm_loop: # 通讯循环 cs.sendto()/cs.recvfrom() # 对话(发送/接收) cs.close() # 关闭客户套接字



在套接字对象创建好之后,我们就进入一个与服务器的对话循环。在通讯结束后,套接字就被 关闭了。tsUclnt.py 真实的代码在例 16.4 中给出。
逐行解释
1-3 行
还是跟 TCP 版本的客户一样,在 Unix 的启动信息行后,我们导入了 socket 模块的所有属性。
5-10 行
因为我们的服务器也是运行在本机,我们的客户还是使用本机和相同的端口号。自然地,缓冲 的大小也还是 1K。创建套接字的方法跟 UDP 服务器中的一样。
12-22 行
UDP 客户的循环基本上与 TCP 客户的完全一样。唯一的区别就是,我们不用先去跟 UDP 服务器建 立连接,而是直接把消息发送出去,然后等待服务器的回复。得到加了时间戳的字符串后,把它显 示到屏幕上,然后再继续其它的消息。在输入结束后,退出循环,关闭套接字。
例 16.4 UDP 时间戳客户 (tsUclnt.py)
创建一个 UDP 客户端,程序会提示用户输入要传给服务器的信息,显示服务器返回的加了时间 戳的结果。

#coding=utf-8
#!/usr/bin/env python
from socket import *

HOST = 'localhost'
PORT = 10086
BUFSIZ = 500
ADDR = (HOST,PORT)

udpCliSock = socket(AF_INET,SOCK_DGRAM)

while True:
data = raw_input('>')
if not data:
break
udpCliSock.sendto(data,ADDR)
data,ADDR = udpCliSock.recv(BUFSIZ)
if not data:
break
udpCliSock.close()













































猜你喜欢

转载自blog.csdn.net/clarence20170301/article/details/76602518