一、服务端
下面是一个简单的 Python 服务端程序的示例,使用标准库中的 socket 模块来建立一个 TCP 服务器。该服务器接收客户端的连接请求,客户端发送一定大小的数据流以测试 TCP 带宽。
实际场景中带宽测试可能需要更复杂的逻辑来确保测试的准确性。
python
import socket
import time
def main():
# 配置服务器地址和端口
host = '0.0.0.0'
port = 12345
# 创建 socket 对象
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as server_socket:
# 绑定地址和端口
server_socket.bind((host, port))
# 开始监听,设置最大连接数
server_socket.listen(5)
print(f"Server listening on port {port}...")
# 接受客户端连接
client_conn, client_addr = server_socket.accept()
print(f"Accepted connection from {client_addr}")
# 开始接收数据
start_time = time.time()
total_received = 0
try:
while True:
# 接收数据,这里的 1024 是接收数据的缓冲大小,单位是字节
data = client_conn.recv(1024)
if not data:
break
total_received += len(data)
finally:
end_time = time.time()
# 关闭客户端连接
client_conn.close()
# 计算并输出带宽测试结果
duration = end_time - start_time
speed = (total_received / (duration * 1024 * 1024)) # Mbps
print(f"Received {total_received} bytes in {duration:.2f} seconds.")
print(f"Speed: {speed:.2f} Mbps.")
if __name__ == "__main__":
main()
为了运行此服务端程序,需要将其保存为 .py 文件,例如 tcp_server.py,然后在终端或命令行中执行它:
bash
python3 tcp_server.py
客户端可以使用相同的 socket 库编写,或者使用现有的带宽测试工具(例如 iperf 或 netcat)来连接并发送数据。
确保服务器和客户端处于多个不同网络段的测试更能准确反映真实的网络带宽情况,而不仅仅是局域网或同一设备间的带宽。
二、客户端
客户端发送指定大小的数据,服务器接收数据。客户端在发送指定次数的数据后,统计总共消耗的时间来计算平均带宽。以下是一个简单的 Python 客户端示例代码,它使用 socket 库来实现 TCP 通信:
1. 发送
python
import socket
import time
# 服务器的IP地址和端口号
SERVER_IP = '192.168.1.1'
SERVER_PORT = 12345
# 数据块大小(字节)
BUFFER_SIZE = 1024 * 1024 # 1MB
# 测试发送次数
ITERATIONS = 10
def main():
# 初始化客户端socket
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 连接到服务器
client_socket.connect((SERVER_IP, SERVER_PORT))
# 准备发送的测试数据,确保每次发送的大小一致
data = b'a' * BUFFER_SIZE
# 记录测试开始的时间
start_time = time.time()
# 循环指定次数发送数据
for _ in range(ITERATIONS):
# 发送数据
client_socket.sendall(data)
# 记录测试结束的时间
end_time = time.time()
# 关闭socket连接
client_socket.close()
# 计算耗费的总时间
total_time = end_time - start_time
print(f"Total time for {ITERATIONS} iterations: {total_time:.2f} seconds")
# 计算平均速度(带宽)
total_bytes_sent = BUFFER_SIZE * ITERATIONS
average_bandwidth = total_bytes_sent / total_time # in bytes per second
average_bandwidth_mbps = (average_bandwidth * 8) / (1024 * 1024) # convert to Mbps
print(f"Average bandwidth: {average_bandwidth:.2f} Bps or {average_bandwidth_mbps:.2f} Mbps")
if __name__ == '__main__':
main()
该程序首先创建了一个 TCP 客户端并连接到服务器。然后,在循环中发送数据,并计算发送这些数据所需的总时间。最后,它关闭 socket,并计算平均带宽。
该程序假设服务器已就绪并准备接收数据。服务器程序应该能够处理来自客户端的连接和数据接收。
这个程序是同步发送的,也就是说在发送过程中客户端会等待服务器接收完毕后再发送,这对于计算准确的带宽是重要的。还需要注意 TCP 的启动慢和拥塞控制算法可能会影响实际的带宽,因此得到的结果仅为近似值。
2.接收
python
import socket
import time
while True:
s = socket.socket()
addr=("服务端地址",服务端口)
print("{}:wait for server connect...".format(time.ctime()))
while True:
#time.sleep(1)
try:
res=s.connect(addr)
print(res)
if not res:
print("connect server",addr)
break
except:
pass
num = 0
data_len = 0
buf_maxsize = 4096
loop_times = 100000
data_maxsize = buf_maxsize*loop_times
begin_time_ns = time.time_ns()
while True:
try:
if data_len == 0:
begin_time = time.time()
data=s.recv(buf_maxsize)
data_len += len(data)
if data_len == data_maxsize: #收到所有数据
break
if not data: #对端关闭了套接字
break
except Exception as e:
print("{}".format(e))
break
passed_time = time.time() - begin_time
passed_time_ns = time.time_ns() - begin_time_ns
print(passed_time)
print(passed_time_ns)
print(data_len)
print('speed: %.2fMB/s' % (data_len/1024/1024/passed_time))
print('buffer size: %dB' % (buf_maxsize))
print('total data len: %dB' % (data_len))
print('Bandwidth: %.2fMbps' % (data_len/1024/1024/passed_time*8))
print("close client socket")
s.send(b'client close')
s.close()
break