-
23/11/30 네트워크프로그래밍카테고리 없음 2023. 11. 30. 10:48
백그라운드 프로세스 : demon ? daemon ?
파일 : 13주차 강의안 : Multithread Socket Programming
3p TCP 멀티스레드 서버
14p threading 모듈을 사용한 멀티스레드- 메인 스레드로 실행되는 main 함수에서 서브스레드를 생성하고 인자와 함께 handler()함수를 지정한다.
- 서브스레드 생성과 실행
2) threading 모듈을 이용한 멀티스레드 구현
15p threading 모듈과 함수 사용한 tcp 채팅프로그램
: 디테일하게 설명 x 핵심만 설명하신다고 하심메인스레드, 서브스레드 여러개
메인스레드
- 소켓 생성
- 서브스레드 생성 및 시작
- 연결 요청 받아 새로운 소켓 생성
- 새로운 소켓을 소켓 리스트에 추가각 스레드는 개인밖에 모르는데
메인스레드는 모두 관리를 해줘야함. 이 관리를 해주는 게 소켓 리스트서브스레드
- 데이터 수신
- 소켓리스트의 모든 소켓에게 데이터 송신
- 데이터가 없으면 소켓 제거7P _thread 를 이용한 멀티 스레드 진행
- 서버 프로그램 실행
- 두 개 이상의 클라이언트 프로그램 실행 client_demo.py
- 서버 프로그램은 첫 번째 클라이언트의 접속 요청을 받아 서브 thread를 생성하여 데이터 수신 handler () 함수를 실행
- 또 다른 클라이언트가 접속 요청하면 연결을 생성하고 서브 thread 를 생성하여 또 다시 handler() 함수를 실행
- 두 번째로 실행되는 handler()함수는 첫 번째 실행된 handler()함수와는 별도로 실행쓰레드 개념
- 파이썬 프로그램은 기본적으로 하나의 스레드 single thread에서 실행
- 즉, 하나의 메인 스레드가 파이썬 코드를 순차적으로 실행
- 코드를 병렬로 실행하기 위해서는 별도의 쓰레드 subthread 생성
- 파이썬에서 스레드를 생성하기 위해서는 threading 모듈 high레벨 혹은 _thread모듈(low레벨)을 사용할 수 있음.
- 일반적으로 스레드 처리를 위해서는 thread모듈을 기반으로 구현된 threading 모듈을 사용하고 있으며, _thread모듈은 (deprecate되어)
거의 사용하고 있지 않음.서버는 소켓메시지를 모든 클라이언트에 전달해주는 역할
6p _thread 모듈 사용한 멀티스레드 구현
#Client import socket port =2500 address=("localhost", port) BUFSIZE = 1024 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(address) while True: msg=input("message to send:") s.send(msg.encode()) data = s.recv(BUFSIZE) print("Recieved message: %s"%data.decode())
16 p threading 모듈과 함수를 사용한 TCP 채팅 프로그램 : threading.Thread 를 이용한 채팅 서버
import socket import threading #데이터를 수신하고 처리하는 함수 def handler(c, a): global connections #전역변수, 서버와 연결된 클라이언트 목록 저장 while True: data = c.recv(2014) for connection in connections: #모든 클라이언트에게 전송 connection.send(bytes(data)) if not data: #데이터가 없으면 목록에서 삭제 connections.remove(c) c.close() break #소켓 생성 sock=socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.bind(("172.21.164.152", 2500)) #여기에 ip 주소 sock.listen(1) connections = [] #서버와 연결된 클라이언트 목록 #서브 스레드의 생성과 실행 while True: print("wating for you") c, a = sock.accept() cThread = threading.Thread(target=handler, args=(c,a)) #서브 스레드 생성 cThread.daemon = True cThread.start() #서브 스레드 실행 connections.append(c) # 새로운 클라이언트를 목록에 추가 print(connections)
#client 부분을 2개를 둬서 서로 채팅 가능
지금은 서로 채팅을 하고 받는 과정에서 살짝 문제가 있지만 작동은 함20p threading 모듈의 파생 클래스를 이용한 TCP 에코 서버 프로그램
이렇게 수행한다는 거 알기만 하면 됨 GUI 소켓 프로그래밍
파이썬 GUI 프로그래밍 개요
기본 윈도창의 구성
- Tkinder 모듈 : TK Interface 의 약어. TK는 Tcl/TK라는 전통적인 GUI 인터페이스 윈도, 리눅스, 맥 등에서 모두 동일한 코드로 사용 가능
- 위젯 Widget : 윈도우 창에 나올 수 있는 문자, 버튼, 체크박스, 라디오 버튼 등을 의미from tkinder import * # tkinter 는 파이썬에서 GUI 관련 모듈을 제공해주는 표준 윈도우 라이브러리
window = Tk() # 이 부분에서 화면을 구성하고 처리 Tk() 는 기본이 되는 윈도우를 반환한다. 이를 루트 윈도우 또는 베이스 윈도우라고 한다. 실행하면 윈도우 창이 화면에 출력된다. 베이스 윈도우를 window 변수에 넣고 7행에서 window.mainloop() 함수 실행 !
window.mainloop()창 귀엽다 ..! 24p threading 모듈을 이용한 서버 프로그램
- 소켓 생성하고 클라이언트와 연결한다- 섭씨 온도를 화씨 온도로 변환하여 전송한다.
while True :
data = conn.recv(BUFSIZE)
if not data:
break
data = float ( data.decode() )30p threading 모듈을 이용한 GUI 클라이언트 프로그램
사용자 화면 구성27P 파이썬 GUI 프로그래밍 개요
파이썬 위젯의 구성
파이썬 GUI 프로그래밍 절차
1. TKinter 라이브러리를 사용하기 위해 메인창인 tk 객체의 인스턴스를 생성2.
왜 오류 ㅠ ㅠ 함수이름을 변수같이 쓸 수 있는 것이 파이썬 c언어는 아니니까
ㅠㅠ from tkinter import* #섭씨 온도를 서버로 전송 def calculate(): temp = float(entry1.get()) # entry1.delete(0,END) temp = (temp*5/9)+32 entry2.insert(0,temp) # global temp # temp = float(entry1.get()) # Read a temp # #entry1.delete(0,END) # 입력창 지운다. # sock.send(str(temp).encode()) #모양 만들기 root = Tk() message_label = Label(text='Enter a temperature(C) ',font=('Verdana', 16)) entry1 = Entry(font=('Verdana', 16), width=5) recv_label = Label(text='Temperature in F ',font=('Verdana', 16)) entry2 = Entry(font=('Verdana', 16), width=5) calc_button = Button(text='전송', font=('Verdana', 12), command = calculate) # 배치 message_label.grid(row=0, column=0, sticky=W) recv_label.grid(row=1, column=0, sticky=W) entry1.grid(row=0, column=1) entry2.grid(row=1, column=1) calc_button.grid(row=0, column=2, padx=10, pady=10) root.mainloop() def handler(sock): while True: try: #수신 데이터가 없으면 예외 발생 r_msg = sock.recv(1024) #메시지 수신 except: #수신 데이터 없음 pass else: #수신 데이터 표시 entry2.delete(0, END) entry2.insert(0, r_msg.decode()) entry1.delete(0, END) sock = socket(AF_INET, SOCK_STREAM) sock.connect(("localhost", 2500)) cThread = threading.Thread(target=handler, args=(sock,)) cThread.daemon = True cThread.start()