25 网络编程(UDP)

上一章介绍的是网络编程的Tcp网络服务,本章主要介绍Udp方式的网络编程。Udp通信方式是面向非连接的。而Tcp是面向连接的类似于打电话的通信方式,而Udp则是类似于校园或者企业机关里的广播,播放广播的不关心是否都听到了,而校园里的学生未必每个人都在听广播。这个例子就很像Udp网络通信,也是udp的缺点,数据在服务器和客户端之间的传递,不能保证数据一定能被正确收到或者发送出去。只能是软件设计者自己通过某种方式主动检验、规避数据丢失,可设计一些原则如果发现数据不对,要求对方重发一次。udp的优点是服务器和客户端程序结构简单,通信传输速率高。

25.1 Udp服务器端程序

Udp服务器端程序由几部份组成,和Tcp服务器端程序的组成有一点儿差异,无listen和accept。

1). 创建服务器套接字

和Tcp一样用socket.socket来创建服务套接字,指定套机字的类型和通信类型socket.SOCK_DGRAM代表是采用udp方式的套接字通信。

import socket
server_socket = socket.socket(AF_INET, SOCK_DGRAM) 

2). 绑定地址和端口 基于套接字通过bind函数对外公布地址和端口号。

server_socket.bind(ip地址, 端口号)

3). 收发数据 * udp收数据用recvfrom函数。

data, addr  = server_socket.recvfrom(字节数)

recvfrom的返回值有两个,第一个是收到的数据,第二个是客户端套接字(地址和端口号),即从那个客户端收到了数据。 * udp发送数据用sendto函数。

server_socket.sendto(数据, addr)

这里的addr是某客户端的套接字(地址和端口号),可以直接指出也可使用recvfrom的第二个返回值。

4).关闭套接字

server_socket.close()

25.2Udp客户端程序

udp客户端程序很简单,只需创建一个udp通信方式的套接字之后就可以接收或发送数据(sendto需要指定服务端的ip和端口)给服务器端了。

25.3 简单的udp通信程序示例

udp服务器端udps.py

from socket import *
from time import ctime,sleep
hosts = ''
port = 5678
addr = (hosts, port)
uss = socket(AF_INET, SOCK_DGRAM)
uss.bind(addr)
i = 0
while True:
    print 'udp Server waiting'
    data,addc = uss.recvfrom(1024)
    if not data: break
    i += 1
    print data, addc
    sleep(2)
    uss.sendto(ctime(), addc)
uss.close()

udp客户端udpc.py

from socket import *
from time import ctime,sleep
hosts = "localhost"
port = 5678
addr = (hosts, port)
usc = socket(AF_INET, SOCK_DGRAM)
i = 0
while True: 
    usc.sendto(str(i), addr)
    data,adds = usc.recvfrom(1024)
    if not data: break
    i += 1
    print i, adds,data
    sleep(2)
usc.close()

测试

开四个终端,一个终端运行服务器端程序udps.py,另外三个终端运行客户端程序udpc.py。程序执行结果截图如下:

可以看出udp通信程序的结果是如此简单好用!最后需要说明一点,在socketserver模块里也有udp部分的内容,可以参考SocketServer.UDPServer示例 自行学习。