본문 바로가기
PYTHON(파이썬)/TKINTER & KIVY

tkinter & socket

by eplus 2024. 10. 29.

테스트 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와 포트에 연결하고 메시지를 제공하는 것입니다. 다음은 이 코드의 주요 구성요소와 기능에 대한 분석입니다.

주요 구성 요소 및 기능

  1. Tkinter 프레임워크 사용 :
    • GUI를 생성하기 위해 Tkinter사용했습니다.
    • Tkinter.Frame, Tkinter.Button, Tkinter.Label등의 요소를 활용하여 UI를 구축하고 있습니다.
    • 부분은 기본적으로 두 개의 프레임으로 나누어져 하위 상단과 하단으로 구성됩니다.
  2. 클래스와 함수 구조 :
    • Application클래스는 Tkinter.Frame사용자를 대신하여 UI를 정의하고 실행하는 역할을 합니다.
    • 주요 문자열은 cmdClose(), displayMsg(), recv_data(), sendData(), startTimer(), stopTimer(), getIp(), getPort(), main()이 있습니다.
  3. 소켓 통신 :
    • 소켓을 통해 서버와 통신하는 기능이 있습니다.
    • sendData()JSON에서 IP와 포트 정보를 담당 서버에 소켓을 연결하고, 데이터를 제공합니다.
    • 소켓 연결 후 수신 상태를 유지하기 위해 recv_data()인증을 보호의 스레드로 실행합니다( start_new_thread사용).
  4. 스레드 사용 :
    • 데이터를 수신하기 위해 특수한 스레드를 사용하여 데이터를 처리합니다.
    • start_new_thread()함수가 사용되어 데이터를 전송하는 스레드를 생성합니다. 이 스레드는 데이터가 수신될 때마다의 메시지를 리스트박스에 추가합니다.
  5. 타이머 기능 :
    • main()JSON은 매 1초마다 호출되어 소켓 연결을 시도하고 현재 시간을 라벨에 표시하는 타이머 기능을 포함합니다.
    • after()함수를 이용하여 작업 시간을 반복적으로 실행합니다.
  6. 텍스트의 IP와 포트 정보 읽기 :
    • getIp(), getPort()함수에서 파일을 입력하는 IP와 포트를 가져옵니다 mip.txt.mport.txt
    • 이 정보는 Text표시됩니다.

코드 분석 및 문제점

  1. 소켓 연결 오류 :
    • 만약 소켓 연결이 실패할 경우에는 except오류 메시지를 displayMsg()통해 블록을 반환하지만, 반복적으로 연결을 시도하면서 CPU를 많이 소모할 가능성이 있습니다.
  2. 목록 크기 제한 :
    • displayMsg()콜롬비아에서 리스트박스의 항목을 최대 10개로 제한하고, 초과하면 첫 번째 항목을 삭제합니다.
    • 이 방식은 메모리 사용을 줄이는 데 도움을 줄 수 있지만 더 많은 로그를 제외하는 경우가 있을 수 있습니다.
  3. 데이터 기능 제한 :
    • sendData()호소에서 연락이 고정된 문자열 "Send Data"입니다.
    • 사용자가 직접 메시지를 입력할 수 있도록 수정하면 더 유용하게 활용될 수 있습니다.
  4. 발생 처리 미흡 :
    • 소켓의 처리 부분은 비교적 비슷합니다. 예를 들어, 연결하지 못함 시 재시도 전략이나, 네트워크 상태에 대응하는 방법 등은 없습니다.
  5. UI 업데이트와 네트워크 통신 :
    • UI 업데이트와 네트워크 통신은 동일한 메인 스레드에서 작동하고 있어 응답성이 떨어질 수 있습니다.
    • 네트워크 통신을 별도의 스레드에서 처리하고, UI는 메인 스레드에서 유지하는 방식으로 수정하는 것이 권장됩니다.
  6. 보안 문제 :
    • 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