<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Udp on My Blog</title><link>/tags/udp/</link><description>Recent content in Udp on My Blog</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Tue, 28 Jun 2016 00:00:00 +0000</lastBuildDate><atom:link href="/tags/udp/index.xml" rel="self" type="application/rss+xml"/><item><title>Python网络编程UDP</title><link>/2016/06/28/python%E7%BD%91%E7%BB%9C%E7%BC%96%E7%A8%8Budp/</link><pubDate>Tue, 28 Jun 2016 00:00:00 +0000</pubDate><guid>/2016/06/28/python%E7%BD%91%E7%BB%9C%E7%BC%96%E7%A8%8Budp/</guid><description>&lt;!-- toc --&gt;
&lt;p&gt;[TOC]&lt;/p&gt;
&lt;p&gt;TCP是建立可靠连接，并且通信双方都可以以流的形式发送数据。相对TCP，UDP则是面向无连接的协议。&lt;/p&gt;
&lt;p&gt;使用UDP协议时，不需要建立连接，只需要知道对方的IP地址和端口号，就可以直接发数据包。但是，能不能到达就不知道了。&lt;/p&gt;
&lt;p&gt;虽然用UDP传输数据不可靠，但它的优点是和TCP比，速度快，对于不要求可靠到达的数据，就可以使用UDP协议。&lt;/p&gt;
&lt;p&gt;我们来看看如何通过UDP协议传输数据。和TCP类似，使用UDP的通信双方也分为客户端和服务器。服务器首先需要绑定端口：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 绑定端口:
s.bind((&amp;#39;127.0.0.1&amp;#39;, 9999))
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;创建Socket时，&lt;code&gt;SOCK_DGRAM&lt;/code&gt;指定了这个Socket的类型是UDP。绑定端口和TCP一样，但是不需要调用&lt;code&gt;listen()&lt;/code&gt;方法，而是直接接收来自任何客户端的数据：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;print(&amp;#39;Bind UDP on 9999...&amp;#39;)
while True:
# 接收数据:
data, addr = s.recvfrom(1024)
print(&amp;#39;Received from %s:%s.&amp;#39; % (addr, data))
s.sendto(b&amp;#39;Hello, %s!&amp;#39; % data, addr)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;recvfrom()&lt;/code&gt;方法返回数据和客户端的地址与端口，这样，服务器收到数据后，直接调用&lt;code&gt;sendto()&lt;/code&gt;就可以把数据用UDP发给客户端。&lt;/p&gt;
&lt;p&gt;注意这里省掉了多线程，因为这个例子很简单。&lt;/p&gt;
&lt;p&gt;客户端使用UDP时，首先仍然创建基于UDP的Socket，然后，不需要调用&lt;code&gt;connect()&lt;/code&gt;，直接通过&lt;code&gt;sendto()&lt;/code&gt;给服务器发数据：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
for data in [b&amp;#39;Superman&amp;#39;, b&amp;#39;Hooby&amp;#39;, b&amp;#39;Huyu&amp;#39;]:
# 发送数据:
s.sendto(data, (&amp;#39;127.0.0.1&amp;#39;, 9999))
# 接收数据:
print(s.recv(1024).decode(&amp;#39;utf-8&amp;#39;))
s.close()
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;从服务器接收数据仍然调用&lt;code&gt;recv()&lt;/code&gt;方法。&lt;/p&gt;
&lt;p&gt;仍然用两个命令行分别启动服务器和客户端测试，结果如下：&lt;/p&gt;
&lt;p&gt;server:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;Bind UDP on 9999...
Received from (&amp;#39;127.0.0.1&amp;#39;, 58531):b&amp;#39;Superman&amp;#39;.
Received from (&amp;#39;127.0.0.1&amp;#39;, 58531):b&amp;#39;Hooby&amp;#39;.
Received from (&amp;#39;127.0.0.1&amp;#39;, 58531):b&amp;#39;Huyu&amp;#39;.
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;client:&lt;/p&gt;</description></item></channel></rss>