내가 한 번도 경험하지 못했던 "멀티 스레드 서버 프로그래밍"을 시작하기에 앞서 뼈대가 될 코드를 만들었다.
서버 코드
import socket
import argparse
import threading
import time
host = "127.0.0.1"
port = 4000
def handle_client(client_socket, addr):
print("접속한 클라이언트의 주소 입니다. : ", addr)
user = client_socket.recv(1024)
string = "안녕하세요? %s 님"%user.decode()
client_socket.sendall(string.encode())
print("1초 후 클라이언트가 종료됩니다.")
time.sleep(1)
client_socket.close()
def accept_func():
global server_socket
#IPv4 체계, TCP 타입 소켓 객체를 생성
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#포트를 사용 중 일때 에러를 해결하기 위한 구문
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
#ip주소와 port번호를 함께 socket에 바인드 한다.
#포트의 범위는 1-65535 사이의 숫자를 사용할 수 있다.
server_socket.bind((host, port))
#서버가 최대 5개의 클라이언트의 접속을 허용한다.
server_socket.listen(5)
while 1:
try:
#클라이언트 함수가 접속하면 새로운 소켓을 반환한다.
client_socket, addr = server_socket.accept()
except KeyboardInterrupt:
server_socket.close()
print("Keyboard interrupt")
print("클라이언트 핸들러 스레드로 이동 됩니다.")
#accept()함수로 입력만 받아주고 이후 알고리즘은 핸들러에게 맡긴다.
t = threading.Thread(target=handle_client, args=(client_socket, addr))
t.daemon = True
t.start()
if __name__ == '__main__':
#parser와 관련된 메서드 정리된 블로그 : https://docs.python.org/ko/3/library/argparse.html
#description - 인자 도움말 전에 표시할 텍스트 (기본값: none)
#help - 인자가 하는 일에 대한 간단한 설명.
parser = argparse.ArgumentParser(description="\nJoo's server\n-p port\n")
parser.add_argument('-p', help="port")
args = parser.parse_args()
try:
port = int(args.p)
except:
pass
accept_func()
클라이언트 코드
import socket
import argparse
#접속하고 싶은 ip와 port를 입력받는 클라이언트 코드를 작성해보자.
# 접속하고 싶은 포트를 입력한다.
port = 4000
if __name__ == '__main__':
#parser와 관련된 메서드 정리된 블로그 : https://docs.python.org/ko/3/library/argparse.html
#description - 인자 도움말 전에 표시할 텍스트 (기본값: none)
#help - 인자가 하는 일에 대한 간단한 설명.
#nargs - 소비되어야 하는 명령행 인자의 수. -> '+'로 설정 시 모든 명령행 인자를 리스트로 모음 + 없으면 경고
#required - 명령행 옵션을 생략 할 수 있는지 아닌지 (선택적일 때만).
parser = argparse.ArgumentParser(description="\nJoo's client\n-p port\n-i host\n-s string")
parser.add_argument('-p', help="port")
parser.add_argument('-i', help="host", required=True)
parser.add_argument('-u', help="user", required=True)
args = parser.parse_args()
host = args.i
user = str(args.u)
try:
port = int(args.p)
except:
pass
#IPv4 체계, TCP 타입 소켓 객체를 생성
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 지정한 host와 prot를 통해 서버에 접속합니다.
client_socket.connect((host, port))
client_socket.sendall(user.encode())
receive_data = client_socket.recv(1024)
print("받은 데이터는 \"", receive_data.decode(), "\" 입니다.", sep="")
# 소켓을 닫는다.
client_socket.close()
print("접속을 종료합니다.")
추가 설명
좌측이 서버, 우측이 클라이언트 이다.
여기에 소켓 서버와 관련된 예제 코드를 몇 개 올려두었다.
python의 threading 모듈을 이용하여 멀티 스레드 소켓 서버를 구축하는 예제 코드를 작성해봤다.
스레드 내부에서 CPU의 연산이 많아진다면 아마 GIL 때문에 성능이 저하될 것이다.
이다음 도전할 과제는 멀티 스레드 소켓 통신을 이용한 실시간 대화 서비스가 될 것 같다.
'Computer_Language > Python' 카테고리의 다른 글
[Python] 파이썬 소켓 서버 프로그래밍 (0) | 2019.11.17 |
---|---|
[Python] 파이썬 eval 과 exec 함수에 대하여 (0) | 2019.10.04 |
[Python] 파이썬 리스트와 튜플의 차이 (0) | 2019.09.05 |
[Python] 파이썬 병렬 프로그래밍 모듈 (Multiprocessing 라이브러리) (1) | 2019.09.01 |