基于UDP的网络程序

UDP (User Datagram Protocol) 是一种面向无连接的、不可靠的传输协议,其不需要像 TCP 一样进行握手和维护连接状态。UDP 在发送数据时不会确保数据能够到达接收方,也不会对数据进行排序和重传。相比之下,UDP 更为轻量级,传输数据的时延更小,因此适用于对数据传输实时性要求比较高、但是对数据可靠性和顺序性要求不高的应用场景,比如音视频传输、网络游戏等。

1.  实验目的

1) 了解和掌握基于UDP的网络程序的运行机制和编程方法;

2)  参考源代码,编写一个网络通信应用程序:客户机发出数据请求命令,服务器根据其命令提供数据;

2.实验环境

1) 浏览器

2)   TCP/IP协议

3)   编程语言:pyhton

3.实验内容:

编写基于UDP协议的通信程序,包括Server与Client两个部分。实现回声程序:即客户端发送消息,服务器端将收到的消息原样会送给客户端。

 提示:服务器端回送消息时,可以进行加工,例如给每个收到的消息加上“服务器回送”+原始消息+服务器端收到消息的时间;

客户端从4字节数据开始发送,采用循环n次的方式,逐渐增大数据量,观察从少量数据的发送到大量数据的发送,时间性能的变化,记录每次发送数据所需时间,利用excel制作曲线图,并与TCP编程的曲线图比较,分析原因。

实验步骤

本次实验传输的数据设为字符串“abcd”,随着传输次数i的增加字符串“abcd”的长度也将以i的平方增长(每100次一个循环),代码思想如下:

python pyaudio回声消除 python回声程序的编写_python pyaudio回声消除

1.单机实验:

   将服务器和客户端的IP地址按以下设置:

python pyaudio回声消除 python回声程序的编写_python pyaudio回声消除_02

python pyaudio回声消除 python回声程序的编写_网络_03

 

注意接下来我们需要先运行服务器端,再次运行客户端时就直接开始输送消息:

服务器接收到成倍增长的“abcd”如图: 

python pyaudio回声消除 python回声程序的编写_python pyaudio回声消除_04

客户端接收到服务器端回送的“abcd”串,并在字符串后给出接收该消息所用的时间(单位为毫秒)如图:

python pyaudio回声消除 python回声程序的编写_udp_05

 

至此说明服务器和客户端已经通信结果成功,在此我设置了100次传输信息(循环次数可自己设置),传输结束后关闭,如图: 

 

python pyaudio回声消除 python回声程序的编写_python pyaudio回声消除_06

 

至此,单机实验完成。

2.多机实验

同单机实验一样,只需将服务器和客户端的IP地址改为当前电脑所使用的IP地址即可。

查看当前电脑的IP地址:

 

python pyaudio回声消除 python回声程序的编写_服务器_07

将server.py中的IP改为当前IP(自己电脑的IP地址)如图:

python pyaudio回声消除 python回声程序的编写_udp_08

 

 在其他电脑上运行client.py

python pyaudio回声消除 python回声程序的编写_python_09

 

能够成功接收到客户端信息,说明实验成功。

代码如下:

server.py

#服务端
import socket
import struct

server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server_socket.bind(('127.0.0.1', 8082))

while True:
        data, client_addr = server_socket.recvfrom(1024)
        msg = data
        print('已收到客户端信息:', msg.decode('utf-8'))

        # 回声功能:将客户端发送的消息再发送回去
        response_data =  msg
        server_socket.sendto(response_data, client_addr)

clien.py

#客户端
import socket
import struct
import time

client_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server_address = ('127.0.0.1', 8082)
while True:
        # 运行时间记录文件
        with open('time.txt', 'w') as f:
          start_time = time.time()
          for i in range(1, 100):
                        msge = 'abcd' * (i ** 2)
                        msg = msge[:1024].encode('utf-8')#缩小发送的数据大小确保每次发送数据不超过1024字节防止溢出
                        client_socket.sendto(msg, server_address)
                        response_data, server_address = client_socket.recvfrom(1024)
                        end_time = time.time()
                        total_time = end_time - start_time
                        f.write(str(total_time))
                        f.write('\n')
                        print('服务器回送信息:', response_data.decode('utf-8'), '\t', total_time)
        break
print('100次信息传输完毕,关闭客户端!')
f.close()

实验结果与分析

为方便统计时间,我添加了一个time.txt(需先在和client.py同一文件目录下创建time.txt文件)的来记录这100次信息传递的运行时间:

python pyaudio回声消除 python回声程序的编写_python_10

 time.txt 

为下面用excel画曲线图做准备。

由单机实验结果建立接收时间(100次)曲线图

python pyaudio回声消除 python回声程序的编写_网络_11

 明显看到,UDP的数据传输是一块一块的传输,这是由于UDP数据传输特点决定的。

由上述UDP传输数据曲线图与上次实验TCP传输数据曲线图进行对比我们可以发现,UDP 通过 IP 协议在网络上进行数据传输,与 TCP 不同的是,UDP 不会对数据进行拆分和合并,一个 UDP 数据包中的数据不会被拆分成多个 IP 数据包,也不会将多个 UDP 数据包合并成一个 IP 数据包。在发送端,UDP 会将数据打包成 UDP 数据报,其中包含源端口号和目标端口号等信息,然后将其交给 IP 层进行发送。在接收端,IP 层将 UDP 数据报传递给 UDP 协议进行处理,解析出其中的数据并将其交给上层应用程序处理。