前言

工具编写用的语言是python,组件采用的是tkiner组件,可以对指定目标地址和端口,发送消息,界面简单清晰




一、构思

在主窗口,用户填写对应的IPV4地址,服务器的端口号,要发送的消息内容,线程数量,发送消息的数量,点击发送按钮,即可发送UDP包给指定的服务器,并且将发送的数据包的大小以及服务器返回的内容,通过子窗口文本的形式展示出来



二、用到的python模块



tkiner模块

目前很火的编程语言:java,python等都有自己GUI界面编写模块,tkiner是python中用于图形化界面编写的模块



tkiner模块下载

win+R 打开运行框,输入cmd

需要安装python环境,并加入到环境变量,才可执行如下的命令

在DOS窗口输入如下命令

pip install tkiner



socket模块

socket模块是python中网络编程必用的模块,编写客户端和服务端的代码,必须采用socket模块进行连接,通信,数据的传输等,在java中也有相应的网络编程模块,socket(AF_INET,SOCK_DGRAM)返回的是一个非连接的通信对象,采用UDP传输,socket(AF_INET,SOCK_STRAM)返回的是一个面向连接的通信对象,采用TCP传输



ThreadPoolExecutor模块

ThreadPoolExecutor模块是python中线程池需要的模块,本次的udp发包小工具,用到了线程池,所以这个模块也是必须的



导入方式

from concurrent.futures import ThreadPoolExecutor



编码实现

由于本次测试的环境都是本地机器,所以客户端代码和服务端代码都是在本地上,话不多说,下面附上代码



客户端

from tkinter import *
import tkinter.messagebox
from socket import *
from concurrent.futures import ThreadPoolExecutor
# 客户端代码
if __name__ == '__main__':
    root = Tk()
    root.geometry("600x600+300+300")
    send_result = []
    get_result_index = 0
    def get_result(args):
        server_address = args[0]
        server_port = args[1]
        send_msg = args[2]
        client_socket = socket(AF_INET,SOCK_DGRAM)
        return_result = client_socket.sendto(send_msg.encode('utf8'),(server_address,int(server_port)))
        serverMsg,serverAddress = client_socket.recvfrom(1024)
        result_Text_Obj = args[3]
        result_Text_Obj.insert('end',"发送字节大小为"+str(return_result)+'\n服务器返回内容#'+serverMsg.decode('utf8')+'\n')

    def sendMsg(ipv4addr,msg,serverPort,thread_pool_number=10,msg_number=100):
        # ipv4addr = ipv4_entry.get()
        # msg = msg_entry.get()
        if (ipv4addr == "" or msg == "" or serverPort==""):
            tkinter.messagebox.showinfo(title="数据异常", message="请填写完整的数据")
        else:
            # 开始连接服务端,发送数据
            # from socket import *
            # serverName = '192.168.3.8'
            # serverPort = 12345
            # clientSocket = socket(AF_INET, SOCK_DGRAM)
            # while 1:
            #     message = input().encode()
            #     clientSocket.sendto(message, (serverName, serverPort))
            #     modifiedMessage, serverAddress = clientSocket.recvfrom(2048)
            #     print(modifiedMessage)
            # clientSocket.close()
            serverName=ipv4addr
            sport = serverPort
            root2 = Tk()
            root2.title("获得结果")
            root2.geometry('300x300+100+100')
            result_Text = Text(root2, width=200, height=200)
            result_Text.place(x=10, y=10, width=280, height=280)
            pool = ThreadPoolExecutor(int(thread_pool_number))
            for i in range(int(msg_number)+1):
                pool.submit(get_result,args=(serverName,sport,msg,result_Text))
            root2.mainloop()


    root.title("UDP消息发送客户端")
    label = Label(root,justify="center",text="IPV4addr",padx="10",pady="10",relief="groove").place(x=100,y=100,width=80,height=50)
    ipv4_entry = Entry(root,justify="center",width="100",relief="groove")
    ipv4_entry.place(x=180,y=100,width=180,height=50)
    ipv4_info_text = Label(root,justify="center",text="例如:192.168.10.100,无需掩码",padx="10",pady="10").place(x=380,y=100,width=180,height=50)
    send_msg_info_text = Label(root,justify="center",text="消息",padx="10",pady="10",relief="groove").place(x=100,y=160,width=80,height=50)
    msg_entry = Entry(root,justify="center",width="100",relief="groove")
    msg_entry.place(x=180,y=160,width=200,height=50)
    port_label = Label(root, justify="center", text="端口号", padx="10", pady="10").place(x=100, y=220,width=100, height=50)
    port_entry = Entry(root,justify="center",width="100",relief="groove")
    port_entry.place(x=210,y=220,width=100,height=50)
    #获取线程数量,使用线程去跑
    thread_pool_number_label = Label(root,justify="center",padx="10",pady="10",text="线程").place(x=100,y=290,width=100,height=50)
    thread_pool_number_entry = Entry(root,justify="center",width="100",relief="groove")
    thread_pool_number_entry.place(x=210,y=290,width=100,height=50)
    thread_pool_info_label = Label(root,justify="center",padx="10",pady="10",text="默认线程数量10").place(x=320,y=290,width=100,height=50)
    #设置发送消息数量
    msg_number_label = Label(root,justify='center',padx="10",pady="10",text="发送数量").place(x=100,y=360,width=100,height=50)
    msg_number_entry = Entry(root,justify="center",width=100,relief="groove")
    msg_number_entry.place(x=210,y=360,width=100,height=50)
    msg_number_info_label = Label(root,justify="center",padx="10",pady="10",text="默认数量100").place(x=320,y=360,width=100,height=50)
    #防止按钮自动触发函数,添加 lambda 函数添加一个参数, 或者去掉括号,不带参数
    send_Btn = Button(root,justify="center",padx="10",pady="10",text="发送",command=lambda:sendMsg(ipv4_entry.get(),msg_entry.get(),port_entry.get(),thread_pool_number_entry.get(),msg_number_entry.get()),width=100,height=50)
    send_Btn.place(x=100,y=420,width=100,height=50)
    root.mainloop()



服务端代码

from socket import *
import datetime
#udp服务端代码
# from socket import *
# serverPort=12345
# serverSocket=socket(AF_INET,SOCK_DGRAM)
# serverSocket.bind(('192.168.3.8',serverPort))
# print('ready')
# while 1:
#     message,clientAddress=serverSocket.recvfrom(2048)
#     modifiedMessage=message.upper()
#     print(modifiedMessage)
#     serverSocket.sendto(modifiedMessage,clientAddress)
serverport = 12345
serverSocket = socket(AF_INET,SOCK_DGRAM)
serverSocket.bind(('127.0.0.1',serverport))
while 1:
    message,clientAddress = serverSocket.recvfrom(1024)
    print(message.decode('utf8')+"####"+str(datetime.datetime.now()))
    serverSocket.sendto(('服务端已收到'+message.decode('utf8')).encode('utf8'),clientAddress)




三、运行结果



客户端

在这里插入图片描述



发送消息

在这里插入图片描述

在这里插入图片描述



服务端

在这里插入图片描述




版权声明:本文为weixin_56319791原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/weixin_56319791/article/details/127317058