The magic circle of Py: let's use Python 3 & Tkinter to implement a message simulator (with simple server code)

magic circle py let use


One 、 introduction

At work , We always meet the need :

We need to send the message in the specified format to the server program , And then the server does some processing , And then send us the processed message .

Or say , We always need it :

When writing a server-side program , Always want to have one that can simulate receiving packets 、 A client program that monitors messages and can reply to them , In this way, it is convenient for us to debug and write the program logic that our server runs .

The former is the perspective of writing client programs , The latter is the perspective of writing server-side programs .

Anyway? , We always want a message Simulator , Be able to receive 、 monitor 、 Send message , It can facilitate the development and testing work related to the message interaction between the client and the server .

I've always had this idea , Recently, I encountered a project with relatively complex message format , If you don't write a message simulator yourself , The logic debugging of server program will be very troublesome .

therefore , I put forward my own requirements for this message simulator :

  1. Can receive the message information from the server
  2. Can send the specified message information to the server
  3. It can be used to monitor the receiving and sending of messages
  4. The message can be edited and saved locally , Messages can also be read locally
  5. To make this project self-contained , It's better to add a simple server-side program written by yourself

therefore , After a few days of fighting , I finally realized the above requirements in a very simple way :
1

that , Now? , Let's implement the simulator together :)

ps: Students who are interested in the code of this project , You can come to me GitHub
wangying2016/Packet_Simulator

Two 、 Demand analysis : choice Python3 & Tkinter

Since we want to make a message Simulator , I also put forward to myself what is mentioned in the introduction 5 A need , So we need to think about how to achieve it .

1. Technology selection

technical , Here I have chosen Python3 & Tkinter, As for why ...

Because I like Python3 & Tkiner ah :)

But then again , For us programmers , Some of the assistive tools at work , Of course, the easier it is to write, the better , The less code you write, the better , The more powerful the library, the better , Its language is native to support UI The library can basically meet our needs .

So , I chose Python3, And because of Tkinter yes Python3 Native support, cross platform UI library , It's powerful and easy to learn , So the tools for implementation are decided .

2. Business choice

Some people may find it strange , We write a little tool , Why the choice of business is also involved ?

Of course , Although we just want to write a message simulator , But we need to build a simple scenario to make it run . In this scenario , Including our server program , Including the message format we need to define for the interaction between the server and the client , These need to be defined .

in addition , The simpler we define our business, the more representative it is , So when we transplant this message simulator to specific projects for use in the future , Or expand , For example, the message format of the interaction between the server and the client , It involves the encryption and decryption of messages 、 Message reading and writing logic , These need to be personalized and expanded according to the specific project .

here , Let's simply define the following business rules :

  1. The scope of the scene
    The message is sent by short connection , That is, every time the message is sent, it will be closed socket Connect . in addition , Whether it's the server or the client , Need to keep a long-term monitor socket Connect , It is mainly responsible for monitoring messages sent by the other party .
  2. Message format
    The format of the message varies from item to item , Here we are as an experimental project , The simplest definition would be fine , Here I define it as follows :
    2

We have made a good choice in technology and business , The rest is to write the code , Which part to start with ?

Certainly UI.

3、 ... and 、 Interface design : Powerful and simple Tkinter

In my code file Sim_Sender.py in , class GUI Is the key class used to implement interface design .

Among them __init__ Method is used to initialize the interface layout , The layout includes an input box 、 A text box 、 Three buttons and a scrolling text box .

in addition , The trigger function bound to the control is also defined in GUI Class , It also includes reading and writing local message files , And the trigger function of the button 、 The contents of the scrolling text box are written and so on .

here , I'll pick a few places with heavy medicine to explain it .

1. Window creation and initialization

Tkinter Windows in are created by Tk() Functionally progressive , It returns a value similar to the window handle , The position and size of the window can be set .

Inherited from Frame( Framework class ) Of GUI Class is the control class of window layout , It initializes the kind of controls displayed on our interface .

if __name__ == '__main__':
...
# Gui
root = Tk()
app = GUI()
...
root.geometry("350x600+300+300")
root.mainloop()

In the code , After defining the window position and size ,root.mainloop() It's us Windows The most familiar window message loop in programming :)

The layout of the window uses pack layout (Tkinter Support pack/grid/place Three layouts ). The core code of layout is of course GUI Class init_ui() Function :

 def init_ui(self):
self.master.title(" Message Simulator ")
self.pack(fill=BOTH, expand=True)
self.frame1 = Frame(self)
self.frame1.pack(fill=X, expand=True)
lbl1 = Label(self.frame1, text=" Identification code ", width=10)
lbl1.pack(side=LEFT, padx=5, pady=5)
self.entry = Entry(self.frame1)
self.entry.pack(fill=X, padx=5, expand=True)
self.frame2 = Frame(self)
self.frame2.pack(fill=X, expand=True)
lbl2 = Label(self.frame2, text=" Message content ", width=10)
lbl2.pack(side=LEFT, anchor=N, padx=5, pady=5)
self.txt = Text(self.frame2, height=10)
self.txt.pack(fill=X, pady=5, padx=5, expand=True)
self.frame3 = Frame(self)
self.frame3.pack(fill=X, expand=True)
button1 = Button(self.frame3, text=" Open local ", command=self.open_local)
button1.pack(side=LEFT, padx=5, pady=5, fill=X, expand=True)
button2 = Button(self.frame3, text=" Save local ", command=self.save_local)
button2.pack(side=LEFT, padx=5, pady=5, fill=X, expand=True)
button3 = Button(self.frame3, text=" Send message ", command=self.send_msg)
button3.pack(side=LEFT, padx=5, pady=5, fill=X, expand=True)
self.frame4 = Frame(self)
self.frame4.pack(fill=X, expand=True)
lbl3 = Label(self.frame4, text=' Log monitoring ')
lbl3.pack(side=LEFT, padx=5, pady=5)
self.frame5 = Frame(self)
self.frame5.pack(fill=BOTH, expand=True)
self.log = scrolledtext.ScrolledText(self.frame5, height=55, width=150)
self.log.pack(side=LEFT, pady=5, padx=5, expand=True)
self.log.focus_set()
self.add_log('packet simulator', 'start listen')

Tkinter It's not hard to learn , Just be able to find the information in the source code on your own , Be able to search for relevant courses online , I won't go into that here .

2. Scroll text box

In the interface , The most difficult control is the scrolling text box at the bottom of the log monitor .
3
This one is used Tkinter Of scrolledtext Control , The most important function of adding log information is as follows :

 def add_log(self, title, msg):
tm = time.localtime(time.time())
fmt_msg = '%s-%s-%s %s:%s:%s %s\n%s\n\n' % (tm.tm_year,
'{:0>2}'.format(tm.tm_mon),
tm.tm_mday,
'{:0>2}'.format(tm.tm_hour),
'{:0>2}'.format(tm.tm_min),
'{:0>2}'.format(tm.tm_sec),
title,
msg)
self.log.insert(INSERT, fmt_msg)
self.log.focus_set()
self.log.yview_moveto(1)

among , It's all about matching the time format , hinder self.log.yview_moveto(1) Function to keep the current display always on the last line ( Realize the function of rolling tracking ).

3. There are other doubts …

If there are other doubts , I recommend one online Tkinter course , It's very good for beginners to learn :
Python Programming with Tkinter

Now? , We implemented the layout of the interface , It can also simulate scrolling log information to show , So what are we going to do next ?

Socket Programming :)

Four 、Socket Programming : The interaction between the server and the client

in the final analysis , This is still a project of interaction between the server and the client . So in addition to the message Simulator , We also need to write a server-side program .

Yes, of course , To simplify the structure of the project as much as possible , We used the initiator's short connection . That is to say , When the originator sends a message , Create your own socket Connect , Close immediately after sending . For message listeners , You need to be monitoring all the time .

1. Server program

The service list program is relatively simple , Just hang the listening message all the time , Just after receiving the message , Need to start another socket Connect to reply to a message .

The following is the code of listening message :

class Server:
"""
Listen for client.
"""
def __init__(self):
# Create socket
tcp_server_socekt = socket(AF_INET, SOCK_STREAM)
# Bind ip & port
server_address = (server_ip, server_port)
tcp_server_socekt.bind(server_address)
# Begin listen
tcp_server_socekt.listen(1)
print('start listen\n')
# Server long connection, client short connection
while True:
# Listen for client's connection
new_socket, client_address = tcp_server_socekt.accept()
# Receive client data
recv_data = str(new_socket.recv(1024), encoding='utf-8')
# if data length is 0, because client close the connect
if len(recv_data) > 0:
print('recv data = [%s]\n' % recv_data)
else:
print('recv data = 0\n')
# Processing message
processor = Processor(recv_data)
send_data = processor.get_msg()
client = Client(send_data)
print('send data = [%s]\n' % send_data)
# Close the client socket
new_socket.close()
# Stop listen
tcp_server_socekt.close()

You can see , After we suspended monitoring , Every time the message is received , It's all called Client() Class to reply to a message , In this class , We have a new connection from the sender socket Connect :

class Client:
"""
Send message to client.
"""
def __init__(self, data):
# Create socket
self.tcp_client_socket = socket(AF_INET, SOCK_STREAM)
# Bind ip & port
self.server_address = (client_ip, client_port)
# Connect to client
self.tcp_client_socket.connect(self.server_address)
# Send data
self.tcp_client_socket.send(bytes(data.encode("utf-8")))
# Close connect
self.tcp_client_socket.close()

therefore , The logic of the server-side program is very simple , It's listening to the message simulator all the time , After receiving the message, it will be processed , Finally, a new connection is created to return .

2. Client program

In fact, the client program is very similar to the server program , It is also a message hanging on the monitoring server , Then a new one socket Connect to send a message .

however , The client program is different , That is to consider multithreading UI And listening threads .

here , stay GUI Class initialization , I started a new thread to monitor messages :

class GUI(Frame):
"""
GUI with tkinter.
"""
def __init__(self):
super().__init__()
# Instance variable
...
# Init ui
self.init_ui()
# Begin listen
t = threading.Thread(target=network)
t.setDaemon(True)
t.start()
def network():
server = Server()
class Server:
"""
Listen message from server.
"""
def __init__(self):
...

The above code should allow you to see the structure of the project , It's very clear .

For client message sending , In fact, it is very similar to the server side :

 def send_msg(self):
# Get parameter
argv1 = self.entry.get().strip()
argv2 = self.txt.get('1.0', END).strip().replace('\n', '')
if len(argv1) != 4:
messagebox.showerror(' error ', ' Please enter 4 Bit identification code ')
return
print('argv1 = [%s], argv2 = [%s]' % (argv1, argv2))
# Make message
maker = Maker()
msg = maker.get_msg(argv1, argv2)
print('send data: \n[%s]\n' % msg)
# Send Data
client = Client(msg)
class Client:
"""
Send message to server.
"""
def __init__(self, data):
# Create socket
self.tcp_client_socket = socket(AF_INET, SOCK_STREAM)
# Bind ip & port
self.server_address = (server_ip, server_port)
# Connect to server
self.tcp_client_socket.connect(self.server_address)
# Send data
self.tcp_client_socket.send(bytes(data.encode("utf-8")))
# Close connect
self.tcp_client_socket.close()
# Add log
data = 'data = [%s]' % data
app.add_log('send data', data)

This is where the packets are grouped , And then call Client Class creates a new socket Connect to send a message .

thus , The core network programming related content of this project is finished .

that , What's left ?

Message reading and writing :)

5、 ... and 、 Message reading and writing : Generating and interpreting

We defined the message format in the requirement analysis , So the corresponding , We need a class that generates messages according to the message format , And a class that interprets messages according to their format .

The class that generates the message :

class Maker:
"""
Packet generate class.
"""
def __init__(self):
self.index = ''
self.content = ''
self.msg = ''
def get_msg(self, index, content):
self.index = index
self.content = content
length = 6 + 4 + 2 + len(content)
self.msg = '{:0>6}'.format(length) + '|' + index + '|' + content
return self.msg
def get_index(self):
return self.index
def get_content(self):
return self.content

Interpreting the class of the message :

class Reader:
"""
Packet analysis class.
"""
def __init__(self, msg):
self.msg = msg
self.index = msg[7:11]
self.content = msg[12:]
def get_index(self):
return self.index
def get_content(self):
return self.content

This is because my message format is defined by myself , I won't go back to , It's worth mentioning , Depending on the complexity of the project , Just extend these two classes , You can support different projects :)

thus , This project is finished ^_^
End of the flower :)

6、 ... and 、 summary

As a consumer, it's my own project , As long as I'm comfortable with it . But of course, this packet simulator has some shortcomings :

  1. The interface is not friendly enough
  2. It's not powerful enough

wait , These can be in the subsequent project development process , Add and implement according to your own ideas .

But then again , I really like it Python Of Tkinter Interface library , Although it's not so good-looking , But as long as you can run Python3 The place of , Can run Tkinter I have to say it's really convenient , Think IDLE That's what it says , Except that the interface isn't cool enough , Other basic also satisfied the demand , Especially suitable for this kind of handy gadget project !

Python3 & Tkinter There is still a long way to go
To be Stronger:)

版权声明
本文为[I've been to places that span an hour]所创,转载请带上原文链接,感谢

  1. 利用Python爬虫获取招聘网站职位信息
  2. Using Python crawler to obtain job information of recruitment website
  3. Several highly rated Python libraries arrow, jsonpath, psutil and tenacity are recommended
  4. Python装饰器
  5. Python实现LDAP认证
  6. Python decorator
  7. Implementing LDAP authentication with Python
  8. Vscode configures Python development environment!
  9. In Python, how dare you say you can't log module? ️
  10. 我收藏的有关Python的电子书和资料
  11. python 中 lambda的一些tips
  12. python中字典的一些tips
  13. python 用生成器生成斐波那契数列
  14. python脚本转pyc踩了个坑。。。
  15. My collection of e-books and materials about Python
  16. Some tips of lambda in Python
  17. Some tips of dictionary in Python
  18. Using Python generator to generate Fibonacci sequence
  19. The conversion of Python script to PyC stepped on a pit...
  20. Python游戏开发,pygame模块,Python实现扫雷小游戏
  21. Python game development, pyGame module, python implementation of minesweeping games
  22. Python实用工具,email模块,Python实现邮件远程控制自己电脑
  23. Python utility, email module, python realizes mail remote control of its own computer
  24. 毫无头绪的自学Python,你可能连门槛都摸不到!【最佳学习路线】
  25. Python读取二进制文件代码方法解析
  26. Python字典的实现原理
  27. Without a clue, you may not even touch the threshold【 Best learning route]
  28. Parsing method of Python reading binary file code
  29. Implementation principle of Python dictionary
  30. You must know the function of pandas to parse JSON data - JSON_ normalize()
  31. Python实用案例,私人定制,Python自动化生成爱豆专属2021日历
  32. Python practical case, private customization, python automatic generation of Adu exclusive 2021 calendar
  33. 《Python实例》震惊了,用Python这么简单实现了聊天系统的脏话,广告检测
  34. "Python instance" was shocked and realized the dirty words and advertisement detection of the chat system in Python
  35. Convolutional neural network processing sequence for Python deep learning
  36. Python data structure and algorithm (1) -- enum type enum
  37. 超全大厂算法岗百问百答(推荐系统/机器学习/深度学习/C++/Spark/python)
  38. 【Python进阶】你真的明白NumPy中的ndarray吗?
  39. All questions and answers for algorithm posts of super large factories (recommended system / machine learning / deep learning / C + + / spark / Python)
  40. [advanced Python] do you really understand ndarray in numpy?
  41. 【Python进阶】Python进阶专栏栏主自述:不忘初心,砥砺前行
  42. [advanced Python] Python advanced column main readme: never forget the original intention and forge ahead
  43. python垃圾回收和缓存管理
  44. java调用Python程序
  45. java调用Python程序
  46. Python常用函数有哪些?Python基础入门课程
  47. Python garbage collection and cache management
  48. Java calling Python program
  49. Java calling Python program
  50. What functions are commonly used in Python? Introduction to Python Basics
  51. Python basic knowledge
  52. Anaconda5.2 安装 Python 库(MySQLdb)的方法
  53. Python实现对脑电数据情绪分析
  54. Anaconda 5.2 method of installing Python Library (mysqldb)
  55. Python implements emotion analysis of EEG data
  56. Master some advanced usage of Python in 30 seconds, which makes others envy it
  57. python爬取百度图片并对图片做一系列处理
  58. Python crawls Baidu pictures and does a series of processing on them
  59. python链接mysql数据库
  60. Python link MySQL database