Python实现大于32Kpkt/s的包速率发包工具

Zss 发表于:

需要将发包速率提升到大于32Kpkt/s,且支持发送单播 组播 广播等类型的UDP数据包

其实最开始就想到了电脑的CPU有很大的关系,不过还是想在比较破的电脑上来实现这个高速率的工具

最近在测试时,需要一个发包工具的速率达到32Kpkt/s,意为每秒32000个数据包,数据包的大小不用去设置,所以为最小值即可,反而数据包大了,我想包传输速度反而变慢了

以往使用的科来发包工具,测试一下发包的最大速率大约为17Kpkt/s,不过这个可能是和电脑的Cpu有关系的,之后尝试了其他的电脑似乎也是差不多
所以没有在此多纠结,想着使用Python来尝试一下,在相同的电脑中使用单线程发包,其实速率也是17Kpkt/s,
那么使用三个线程来同时发送,速度有了很明显的提升,一下子到了50Kpkt/s左右

测试过程中需要构造UDP的单播,组播,和广播,且使用不同的速率来测试,其实收端不需要写,因为数据包只需要通过AP就可以了,并不会导致结果的影响,为了去测试一个客户遇到的问题,不过接收端比较简单,接收到不需要做任何处理

发送端:

#coding:utf-8
from socket import *
from threading import Thread
import time

def Broadcast():
    if speed == '1':
        for i in xrange(500000):
            udpsocket.sendto('',('192.168.99.255',8888))
    if speed == '2':
        for i in xrange(400000):
            udpsocket.sendto('',('192.168.99.255',8888))
            time.sleep(0.0005)

def Multicast():
    if speed == '1':
        for i in xrange(500000):
            udpsocket.sendto('',('224.0.1.0',8888))
    if speed == '2':
        for i in xrange(400000):
            udpsocket.sendto('',('224.0.1.0',8888))
            time.sleep(0.0005)

def Unicast(ip):
    if speed == '1':
        for i in xrange(500000):
            udpsocket.sendto('',(ip,8888))
    if speed == '2':
        for i in xrange(400000):
            udpsocket.sendto('',(ip,8888))
            time.sleep(0.0005)


def send(task):

    T_list = []
    if task == 'Unicast':
       print('-'*30)
        ip = raw_input('输入AP的ip:')
        print('正在发包中,请稍后...')
        if speed == '1':number = 3
        if speed == '2':number = 1
        s_time = time.time()
        for i in range(number):
            T = Thread(target=Unicast,args=(ip,))
            T.start()
            T_list.append(T)
    if task == 'Multicast':
       print('-'*30)
        print('正在发包中,请稍后...')
        if speed == '1':number = 3
        if speed == '2':number = 1
        s_time = time.time()
        for i in range(number):
            T = Thread(target=Multicast)
            T.start()
            T_list.append(T)
    if task == 'Broadcast':
       print('-'*30)
        print('正在发包中,请稍后...')
        if speed == '1':number = 3
        if speed == '2':number = 1
        s_time = time.time()
        for i in range(number):
            T = Thread(target=Broadcast)
            T.start()
            T_list.append(T)
    for a in T_list:
        a.join()
    run_time = int(time.time() - s_time)-4
    print('-'*30)
    if speed == '1':
        rate = int(1500000/run_time)/1000
        print('发包时长约:%5.2fs\n发包总数:1500Kpkt\n平均发包速率约:%dKpkt/s'%(run_time,rate))
        print('AP应当收到的包大约为:%dKpkt,收到的包应当远小于1500Kpkt'%(run_time*32))
    else:
        rate = int(400000/run_time)/1000
        print('发包时长约:%5.2fs\n发包总数:400Kpkt\n平均发包速率约:%dKpkt/s'%(run_time,rate))
        print('AP应当收到的包应当为:400Kpkt')
    print('-'*30)


def input_choice():
    print('-'*30)
    print('IP为: %s'%localip)
    print('端口为: 7777')
    print('-'*30)
    print('(1).发送广播')
    print('(2).发送组播')
    print('(3).发送单播')
    print('-'*30)
    choice = raw_input('输入你的选择:')
    return choice

def input_speed():
    print('-'*30)
    print('(1).速率 > 32Kpkt/s')
    print('(2).速率 < 32Kpkt/s')
    print('-'*30)
    choice = raw_input('输入你的选择:')
    return choice


if __name__ == '__main__':
    localip = gethostbyname(gethostname())
    udpsocket = socket(AF_INET,SOCK_DGRAM)
    udpsocket.bind(('',7777))
    choice = input_choice()
    speed = input_speed()
    if choice == '1':
        send('Broadcast')
    elif choice == '2':
        send('Multicast')
    elif choice == '3':
        send('Unicast')
    else:pass
    raw_input()

接收端:

from socket import *


if __name__ == '__main__':
    localip = localip = gethostbyname(gethostname())
    print "Server ip is %s"%localip
    print "Server port is 8888"
    print 'Server is running'
    while 1:
        udpsocket = socket(AF_INET,SOCK_DGRAM)
        udpsocket.bind(('',8888))
        udpsocket.recvfrom(1472)