테스트 SAMPLE PROGRAM
##########################################
# eIOT - IF Main
# Date : 2023.5.4 By: EPLUS
##########################################
import tkinter
from datetime import datetime
import time
import socket
from _thread import *
###################################
# 함수 정의 ---
###################################
def cmdClose():
quit()
def displayMsg(window, smsg):
now = time.strftime("%Y-%m-%d %H:%M:%S")
stime = time.strftime("%H:%M:%S")
icnt = window.listbox.size()
if icnt==10:
window.listbox.delete(0,0)
window.listbox.insert(icnt, str(stime)+" >> "+ smsg)
window.listbox.pack(side="left")
def recv_data(window, client_socket):
while True :
data = client_socket.recv(1024)
sdata = repr(data.decode())
if len(data) != 0:
displayMsg(window, sdata)
def sendData(window):
sip = window.textip.get(1.0,"end")
sip = sip.replace('\n','')
sport = window.textport.get(1.0,"end")
sport = sport.replace('\n','')
HOST = sip
PORT = int(sport)
try:
client_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
client_socket.connect((HOST, PORT))
start_new_thread(recv_data, (window, client_socket,))
smsg = "Send Data"
client_socket.send(smsg.encode())
except:
displayMsg(window, "Socket 접속오류!!!")
#
###################################
# 화면 정의 및 Start
# => 향후 쓰레드 검토 : threading
###################################
class Application(tkinter.Frame):
def __init__(self, master):
super().__init__(master)
self.timer = None
self.master = master
self.master.title("eIOT_MAIN_V1.0")
self.pack(fill='both', expand=True)
now = time.strftime("%Y-%m-%d %H:%M:%S")
# Frame 설정 - 상단, 하단
self.frame = tkinter.Frame(self, relief="solid", bg="white", bd=1)
self.frame.pack(side="top", fill="x", expand=False)
self.frameB = tkinter.Frame(self, relief="solid", bg="yellow", bd=1)
self.frameB.pack(side="bottom", fill="x", expand=False)
# Button 설정 - Start & 종료 버튼
self.button = tkinter.Button(self.frame, overrelief="solid", width=10, relief="raised", font="굴림체", height=1, command=cmdClose, text="종료" )
self.button.pack(side="right")
# Label
sdate = time.strftime('%Y-%m-%d')
self.label = tkinter.Label(self.frame, text="일자 : "+sdate, width=20, height=1, bg="white", bd=2, font="굴림체", relief="flat" )
self.label.pack(side="left")
self.labelM = tkinter.Label(self.frameB, text="", width=200, height=2, bg="yellow", relief="solid" )
self.labelM.pack(side="left")
# ListBox
self.listbox = tkinter.Listbox(self, selectmode='extended', font="굴림체", fg="white", bg="black", bd=1, width=760)
# Text
self.textport = tkinter.Text(self.frame, width=5, height=1, font="굴림체", bg="yellow")
self.textport.pack(side="right")
self.textip = tkinter.Text(self.frame, width=18, height=1, font="굴림체", bg="yellow")
self.textip.pack(side="right")
sip = self.getIp()
sport = self.getPort()
self.textip.insert("current", sip)
self.textport.insert("current", sport)
self.main()
def startTimer(self, *_):
self.main()
def stopTimer(self, *_):
self.after_cancel(self.timer)
def getIp(self):
sip = ""
file = open("mip.txt",'r')
sip = file.read()
sip = sip.replace('\n','')
return sip
def getPort(self):
sport = ""
file = open("mport.txt",'r')
sport = file.read()
sport = sport.replace('\n','')
return sport
def main(self):
now = time.strftime("%Y-%m-%d %H:%M:%S")
stime = time.strftime("%H:%M:%S")
# 소켓 전송
sendData(self)
self.labelM.config(text=str(now))
#
self.timer = self.after(1000, self.main)
# Main
root = tkinter.Tk()
root.geometry("760x290+1+1")
#
app = Application(root)
#
app.mainloop()
ChatGPT가 분석한 내용
이 코드는 TkinterGUI를 이용하여 소켓 통신을 수행하는 기능입니다. 주요은 GUI 인터페이스를 통해 특정 IP와 포트에 연결하고 메시지를 제공하는 것입니다. 다음은 이 코드의 주요 구성요소와 기능에 대한 분석입니다.
주요 구성 요소 및 기능
- Tkinter 프레임워크 사용 :
- GUI를 생성하기 위해 Tkinter사용했습니다.
- Tkinter.Frame, Tkinter.Button, Tkinter.Label등의 요소를 활용하여 UI를 구축하고 있습니다.
- 부분은 기본적으로 두 개의 프레임으로 나누어져 하위 상단과 하단으로 구성됩니다.
- 클래스와 함수 구조 :
- Application클래스는 Tkinter.Frame사용자를 대신하여 UI를 정의하고 실행하는 역할을 합니다.
- 주요 문자열은 cmdClose(), displayMsg(), recv_data(), sendData(), startTimer(), stopTimer(), getIp(), getPort(), main()이 있습니다.
- 소켓 통신 :
- 소켓을 통해 서버와 통신하는 기능이 있습니다.
- sendData()JSON에서 IP와 포트 정보를 담당 서버에 소켓을 연결하고, 데이터를 제공합니다.
- 소켓 연결 후 수신 상태를 유지하기 위해 recv_data()인증을 보호의 스레드로 실행합니다( start_new_thread사용).
- 스레드 사용 :
- 데이터를 수신하기 위해 특수한 스레드를 사용하여 데이터를 처리합니다.
- start_new_thread()함수가 사용되어 데이터를 전송하는 스레드를 생성합니다. 이 스레드는 데이터가 수신될 때마다의 메시지를 리스트박스에 추가합니다.
- 타이머 기능 :
- main()JSON은 매 1초마다 호출되어 소켓 연결을 시도하고 현재 시간을 라벨에 표시하는 타이머 기능을 포함합니다.
- after()함수를 이용하여 작업 시간을 반복적으로 실행합니다.
- 텍스트의 IP와 포트 정보 읽기 :
- getIp(), getPort()함수에서 파일을 입력하는 IP와 포트를 가져옵니다 mip.txt.mport.txt
- 이 정보는 Text표시됩니다.
코드 분석 및 문제점
- 소켓 연결 오류 :
- 만약 소켓 연결이 실패할 경우에는 except오류 메시지를 displayMsg()통해 블록을 반환하지만, 반복적으로 연결을 시도하면서 CPU를 많이 소모할 가능성이 있습니다.
- 목록 크기 제한 :
- displayMsg()콜롬비아에서 리스트박스의 항목을 최대 10개로 제한하고, 초과하면 첫 번째 항목을 삭제합니다.
- 이 방식은 메모리 사용을 줄이는 데 도움을 줄 수 있지만 더 많은 로그를 제외하는 경우가 있을 수 있습니다.
- 데이터 기능 제한 :
- sendData()호소에서 연락이 고정된 문자열 "Send Data"입니다.
- 사용자가 직접 메시지를 입력할 수 있도록 수정하면 더 유용하게 활용될 수 있습니다.
- 발생 처리 미흡 :
- 소켓의 처리 부분은 비교적 비슷합니다. 예를 들어, 연결하지 못함 시 재시도 전략이나, 네트워크 상태에 대응하는 방법 등은 없습니다.
- UI 업데이트와 네트워크 통신 :
- UI 업데이트와 네트워크 통신은 동일한 메인 스레드에서 작동하고 있어 응답성이 떨어질 수 있습니다.
- 네트워크 통신을 별도의 스레드에서 처리하고, UI는 메인 스레드에서 유지하는 방식으로 수정하는 것이 권장됩니다.
- 보안 문제 :
- IP 주소와 포트 번호를 텍스트 파일로 저장하고 입력하는 방식은 보안에 있을 수 있습니다.
- 다양한 기능을 설정하여 파일로 파일을 저장하는 등의 보안 강화가 필요합니다.
개선 방향
- UI와 통신의 분리 : 현재 코드에서는 UI 스레드와 네트워크 통신이 작은 루프에서 동작하는 구조입니다. 네트워크 통신은 별도의 스레드에서 수행하고, UI 스레드와 감시로 변경하여 작업의 응답성을 즐길 수 있습니다.
- 처리 강화 : 소켓 연결 실패 시 일정 시간을 재시도하도록 처리를 강화할 수 있습니다. 이 서비스는 계속해서 연결될 수 있습니다.
- 사용자 입력 기능 추가 : 메시지를 직접 입력하고 할 수 있는 텍스트 상자를 추가하면 사용자와 결합된 복합이 복합될 것입니다.
- 로그 추가 :리스트박스에 로그인을 허용하는 파일에 저장하는 기능을 추가하여 로그를 나중에 참조할 수 있도록 할 수 있도록 할 것입니다.
이 코드의 주요 기능은 네트워크 통신과 로그인 기록을 통해 GUI를 통해 간단히 보여주는 것입니다. 독립 통신 부분과 UI 부분의 분리가 필요하고 처리할 수 있는 강화 기능이 있어야 더 특별할 수 있습니다.
728x90
반응형
'PYTHON(파이썬) > TKINTER & KIVY' 카테고리의 다른 글
| kivy로 윈도우용 GUI 구현하기 (1) | 2024.10.29 |
|---|---|
| GUI 툴 kivy란? (크로스 플랫폼) (9) | 2024.10.29 |
| tkinter를 APP로 전환은? (1) | 2024.10.29 |
| tkinter & opencv (0) | 2024.10.29 |
| tkinter (GUI) (0) | 2024.10.29 |