功能描述:

创建UDP套接字进行通信,重点演示UDP套接字对象方法connect()和bind()的作用。

首先,编写一个“服务端”代码,用来被动接收发送端的信息然后做出一定的响应,向对方连续发送10个字节串。代码如下:

Python演示--UDP套接字真的无连接吗?_套接字

这个接收端的功能很简单,就是收到消息后原路发回10个信息。如果收到的是bye就关闭套接字。

接下来我们编写一个发送端程序,代码如下:

Python演示--UDP套接字真的无连接吗?_udp_02

 

正常情况下,这两个程序会工作的很好,如图:

Python演示--UDP套接字真的无连接吗?_套接字_03

但是如果这个过程被干扰,就不会这样顺利了。编写下面这个代码的人通过某个途径知道了发送端“UDP套接字调用connect_demo2.py"正在使用的端口号,然后直接向其发送信息,试图干扰1和2的工作。代码如下:

Python演示--UDP套接字真的无连接吗?_python_04

在攻击者的干扰下,原来的通信双方正常通信过程被干扰,示例如下:

Python演示--UDP套接字真的无连接吗?_python_05

如何避免demo2接收到非通信对方发来的干扰信息呢?其实不难做到,只需要在接收到信息之后检查一下对方地址就可以了,例如:

Python演示--UDP套接字真的无连接吗?_python_06

这样的话,demo3的运行过程就不会收到attack的影响了,运行过程如下:

Python演示--UDP套接字真的无连接吗?_udp_07

这样处理虽然可以解决问题,但略显笨拙。实际上套接字已经提供了更好的解决方案,那就是在UDP套接字发送端调用connect()方法明确指定通信对方地址,这样的话就会在底层自动过滤其他地址发来的任何信息了,例如:

Python演示--UDP套接字真的无连接吗?_UDP_08

在UDP发送端调用connect()方法注册指定地址为默认通信地址之后,可以使用send()直接向默认地址发送信息,也可以使用recv()直接从对方接收信息,不再需要使用sendto()和recvfrom(),并且recv()会自动过滤其他地址发来的信息,可以避免被第三方攻击。运行过程如下:

Python演示--UDP套接字真的无连接吗?_udp_09

由上可知,UDP是无连接协议这一点是一定的,没有任何疑问。但UDP套接字确实是可以调用connect()方法的,只不过调用connect()并不是真的要连接谁,只是在系统中标记一下通信对方的地址。这样的话,收发信息的代码可以简洁很多,并且可以避免来自第三方的攻击。