: 채팅프로그래밍 순천향대학교컴퓨터공학과 이상정 순천향대학교컴퓨터공학과 1 학습내용 인터넷구조 인터넷구성요소 인터넷주소 클라이언트 / 서버구조 소켓프로그래밍소개 파이썬소켓프로그래밍 TCP 클라이언트 / 서버프로그래밍 스레드소개 파이썬스레드 채팅클라이언트 / 서버프로그램 순천향대학교컴퓨터공학과 2
네트워크요소 네트워크가장자리 (edge) 호스트 : 클라이언트와서버 데이터센터내의서버들 접속네트워크 (access network), 물리매체 (physical media) 유무선통신링크 네트워크코어 (core) 라우터 네트워크들의네트워크 순천향대학교컴퓨터공학과 3 클라이언트 / 서버구조 서버 (server) 항상켜져있는호스트 서비스제공 고정 IP 주소 데이터센터로확장 클라이언트 (client) 서버와통신 서비스요청 클라이언트들간직접통신하지않음 유동 IP 가질수있음 항상연결되어있지않고간헐적으로통신할수있음 순천향대학교컴퓨터공학과 4
인터넷주소 인터넷주소는 IP 주소와포트번호로구분 IP 주소 호스트 / 라우터주소 IPv4 주소 : 32 비트 32 비트 IP 주소공간이빠른속도로고갈되어가고있음 => IPv6: 128 비트 포트번호 호스트내의프로세스 ( 프로그램 ) 을구분하는번호 예 HTTP 서버 :80 80, 메일서버 :25 순천향대학교컴퓨터공학과 5 소켓 (Socket) 프로세스는소켓 (socket) 을통해네트워크로메시지를송수신 소켓은호스트의애플리케이션계층과트랜스포트계층간의인터페이스 프로세스는집 (house), 소켓은출입구 (door) 에비유 송신프로세스는출입구 ( 소켓 ) 바깥네트워크로메시지를밀어냄 소켓은애플리케이션과네트워크사이의 API(Application Programming Interface) 순천향대학교컴퓨터공학과 6
소켓프로그래밍 두가지형태의트랜스포트서비스 UDP: 비연결형, 비신뢰적인데이터전송 TCP: 연결형, 신뢰적인데이터전송 TCP 소켓프로그래밍 서버프로세스가먼저수행중에있어야함 서버는클라이언트의초기접속을처리하는소켓을생성해야함 클라이언트는서버에초기접속 클라이언트는 TCP 소켓을생성하고, 서버프로세스의 IP 주소와포트번호를명시하여서버에접속 서버는클라이언트에의해초기접속클라이언트와통신하는서버프로세스를위한새로운소켓 ( 연결소켓 ) 을생성 서버와클라이언트가데이터송수신 순천향대학교컴퓨터공학과 7 TCP 클라이언트 / 서버소켓상호동작 순천향대학교컴퓨터공학과 8
TCP 클라이언트 / 서버소켓상호동작 파이썬 순천향대학교컴퓨터공학과 9 파이썬소켓 소켓생성 소켓라이브러리 : socket 모듈 소켓생성 socket.socket(family, type, proto=0) 함수 : return socket family: 프로토콜표시, 인터넷인경우 AF_INET type: 인터넷인경우트랜스포트서비스표시 TCP: SOCK_STREAM, UDP: SOCK_DGRAM socket 객체를리턴 TCP 소켓생성예 serversocket = socket(af_inet, SOCK_STREAM) STREAM) 소켓종료 socket.close() close() 메소드 순천향대학교컴퓨터공학과 10
파이썬소켓 서버연결초기화 주소와소켓결합 서버의주소 (IP 주소, 포트번호 ) 를생성된소켓과결합 socket.bind(address) 메소드 address: (host IP 주소, 포트 ) 튜플 연결요청청취 튜플 (tuple) 은리스트와거의비슷하나리스트와달리요소의변경 ( 추가, 삭제등 ) 할수없음 클라이언트로부터소켓연결요청을청취 socket.listen(backlog) 메소드 backlog: 허용되는최대요청수 연결수락 클라이언트의연결요청을수락 socket.accept() 메소드 : return (socket, address) 클라이언트와통신을위한새로운연결소켓과클라이언트의주소를리턴 순천향대학교컴퓨터공학과 11 파이썬소켓 서버연결초기화예 서버연결초기화예 서버의 IP 주소가 '229.78.56.90' 이라고가정 서버인경우 IP 주소생략가능, ' ' 7000 번포트번호로클라이언트의연결요청을청취하는예 # 호스트주소지정 servername = '229.78.56.90'' serverport = 7000 # 소켓생성 serversocket = socket(af_inet, SOCK_STREAM) # 주소와소켓결합 serversocket.bind((servername, serverport)) # 연결요청청취 serversocket.listen(5) # 연결요청수락, 연결소켓생성 connectionsocket, addr = serversocket.accept() 순천향대학교컴퓨터공학과 12
파이썬소켓 클라이언트연결초기화 서버에연결요청 서버에연결을요청 socket.connect(address) 메소드 address는서버주소 (IP, 포트 ) # 연결할서버주소지정 servername = '229.78.56.90' serverport = 7000 # 소켓생성 clientsocket = socket(af_inet, SOCK_STREAM) # 서버에연결요청 clientsocket.connect((servername, serverport)) 순천향대학교컴퓨터공학과 13 파이썬소켓 데이터송수신 데이터송신 socket.send(bytes) 메소드 : return bytes_num bytes: 보내질바이트데이터들 보내진데이터의바이트수리턴 데이터수신 socket.recv(bufsize) 메소드 : return bytes bufsize: 한번에받을수있는최대데이터의바이트수 받은데이터의바이트들리턴 data = input('input string: ') clientsocket.send(data.encode("utf8")) # 문자열인코드하여송신 data = clientsocket.recv(1024) # 데이터수신 print(data) 순천향대학교컴퓨터공학과 14
TCP 소켓프로그램예소개 1. 클라이언트는키보드로한줄의문자 ( 데이터 ) 를읽고, 그데이터를서버로송신 2. 서버는데이터를수신하고, 문자를대문자로변환 3. 서버는수정된데이터를클라이언트에게송신 4. 클라이언트는수정된데이터를수신하고화면에출력 한컴퓨터에서 2 개의파이썬셀수행하여클라이언트 / 서버 통신 자기자신을나타내는루프백 (loopback) 주소사용 127.0.0.1 윈도우에서자기자신의주소를알려면콘솔창에서 ipconfig 명령 c> ipconfig 순천향대학교컴퓨터공학과 15 TCP 프로그램예 서버프로그램 ### TCP 서버프로그램 from socket import * # 네트워크 TCP 연결초기화 print("server TCP initialize...") # 호스트주소지정 serverport = 7000 # 서버소켓생성 serversocket = socket(af_inet, SOCK_STREAM) # 주소와소켓결합 serversocket.bind(('', serverport)) # 연결요청청취 serversocket.listen(1) while True: # 연결요청수락, 연결소켓리턴 connectionsocket, addr = serversocket.accept() print("client connected...", addr) # 데이터수신 rawdata = connectionsocket.recv(1024) print("receive: ", rawdata.decode("utf8")) # 대문자변환 upperstr = rawdata.upper() # 데이터송신 connectionsocket.send(upperstr) connectionsocket.close() 순천향대학교컴퓨터공학과 16
TCP 프로그램예 클라이언트프로그램 ### TCP 클라이언트프로그램 from socket import * # 네트워크 TCP 연결초기화 print("client TCP initialize...") # 연결할서버주소지정 servername = '127.0.0.1' serverport = 7000 # 클라이언트소켓생성 clientsocket = socket(af_inet, SOCK_STREAM) # 서버에연결요청 clientsocket.connect((servername, serverport)) print("server connected...") rawdata = input('input string: ') # 문자열인코드하여데이터송신 clientsocket.send(rawdata.encode("utf8")) # 데이터수신 modifiedstr = clientsocket.recv(1024) print("from server: ", modifiedstr.decode("uft8")) 순천향대학교컴퓨터공학과 17 시험주행 순천향대학교컴퓨터공학과 18
TCP 프로그램예동작검토 앞의예제프로그램 서버프로그램에서같은클라이언트연결에대해서도매번연결요청수락 루프내에서연결요청수락 클라이언트한번데이터송수신후종료 데이터수신시동작 데이터수신시데이터를받을때까지프로그램이블록킹 (blocking) 데이터수신까지프로그램이다른동작을못함 개선된프로그램 채팅프로그램 한번연결수락으로클라이언트종료하지않고계속데이터송수신 루프밖에서연결요청수락 데이터수신블록킹문제 데이터수신동작을독자적인프로그램 ( 스레드 ) 로실행하여해결 순천향대학교컴퓨터공학과 19 파이썬스레드생성및실행 스레드라이브러리 : threading 모듈 스레드생성 threading.thread(target= 함수이름, args=( 인수, )) 함수 : return Thread target: 실행될함수이름 args: 함수에전달될인수튜플로표시되며인수가없으면생략인수가하나인경우는 ( 인수,) 로표시 Thread 객체를리턴 스레드생성예 t = Thread(target=func, args = (10, 20)) 스레드실행 Thread.start() 메소드 순천향대학교컴퓨터공학과 20
from threading import * 스레드예 # 스레드로실행되는함수 def testprint(m, n=5): print("testprint(%d) "%m) for i in range(m,n): print(" %d" %i) # 스레드생성및실행 th = Thread(target=testPrint, t t tp t args=(2,)) th.start() print("mainprint i i t ") for i in range(100,106): print(" %d" %i) # 스레드생성및실행 th = Thread(target=testPrint, args=(30,35)) th.start() 순천향대학교컴퓨터공학과 21 시험주행 순천향대학교컴퓨터공학과 22
채팅프로그램예 클라이언트와서버가서로문자를주고받는채팅프로그램예 한번연결수락으로클라이언트종료하지않고계속데이터송수신 루프밖에서연결요청수락 데이터수신동작을독자적인프로그램 ( 스레드 ) 로실행 한글송수신을위해 UTF8 인코드 / 디코드 파이썬 GUI에서는수신문자가바로출력되지않을수도있음 => 윈도우프롬트창에서실행 문제점 1:1 채팅프로그램 다 : 다채팅프로그램은비동기입출력필요 => 파이썬은 select 모듈제공 순천향대학교컴퓨터공학과 23 ### 채팅서버프로그램 from socket import * from threading import * 채팅프로그램예 서버프로그램 # 연결요청수락, 연결소켓리턴 connectionsocket, addr = serversocket.accept() print(" 클라이언트연결됨...", addr, " n") # 메시지수신함수 ( 스레드 ) def serverrecv(): while True: # 데이터수신하고, 디코드하여출력 clientmsg = connectionsocket.recv(1024) print("[ 클라이언트 ] " + clientmsg.decode("utf8") + " n") # 서버네트워크연결초기화 print(" 서버네트워크연결초기화...") # 호스트주소지정 serverport = 7000 # 서버소켓생성 serversocket = socket(af_inet, SOCK_STREAM) # 주소와소켓결합 serversocket.bind(('', serverport)) # 연결요청청취 serversocket.listen(1) 순천향대학교컴퓨터공학과 24 # 스레드생성및실행 Thread(target=serverRecv).start() () while True: # 송신데이터입력 rawdata = input() # 문자열인코드하여데이터송신 connectionsocket.send(rawdata.encode("utf8")) connectionsocket.close()
채팅프로그램예 클라이언트프로그램 ### 채팅클라이언트프로그램 from socket import * from threading import * # 서버에연결요청 clientsocket.connect((servername, t t(( serverport)) print(" 서버연결됨... n") # 메시지수신함수 ( 스레드 ) def clientrecv(): while True: # 데이터수신하고, 디코드하여출력 servermsg = clientsocket.recv(1024) print("[ 서버 ] " + servermsg.decode("utf8") + " n") clientsocket.close() # 클라이언트네트워크연결초기화 print(" 클라이언트네트워크연결초기화...") # 연결할서버주소지정 servername = '127.0.0.1' serverport = 7000 # 클라이언트소켓생성 clientsocket = socket(af_inet, SOCK_STREAM) 순천향대학교컴퓨터공학과 25 # 스레드생성및실행 Thread(target=clientRecv).start() while True: # 송신데이터입력 rawdata = input() # 문자열인코드하여데이터송신 clientsocket.send(rawdata.encode("utf8")) t t d (" tf8")) clientsocket.close() 시험주행 순천향대학교컴퓨터공학과 26
과제 1. 앞에서소개된채팅프로그램을작성하고실행 2. 앞에서배운내용을사용한임의의프로그램작성 프로그램설명 프로그램소스 실행결과 순천향대학교컴퓨터공학과 27